Commit 8111df5b authored by xuchaozou's avatar xuchaozou

feat: 增加结束对话

parent 9509982a
Pipeline #86546 waiting for manual action with stages
...@@ -26,7 +26,7 @@ const PandaUi = props => { ...@@ -26,7 +26,7 @@ const PandaUi = props => {
return () => { return () => {
event.off('record:changedStaus', changeSwitch); event.off('record:changedStaus', changeSwitch);
}; };
}, [changeSwitch]); }, []);
const changeSwitch = useCallback( const changeSwitch = useCallback(
async ({ recordData, e: checked }) => { async ({ recordData, e: checked }) => {
......
...@@ -4,18 +4,23 @@ import { Tooltip, Typography } from 'antd' ...@@ -4,18 +4,23 @@ import { Tooltip, Typography } from 'antd'
import { Fragment, useCallback, useContext, useEffect, useRef, useState } from 'react' import { Fragment, useCallback, useContext, useEffect, useRef, useState } from 'react'
import { event } from '@wisdom-utils/utils' import { event } from '@wisdom-utils/utils'
import moment from 'moment' import moment from 'moment'
import { Directive, AllDirectiveTypes } from '../../core' import { Directive, AllDirectiveTypes, CloseSessionDirective } from '../../core'
import context from '../../config' import context from '../../config'
import SparkDirective from '../../core/directive/SparkDirective' import SparkDirective from '../../core/directive/SparkDirective'
const Dialog = props => { const Dialog = props => {
const { globalConfig, setGlobalConfig } = useContext(context) const { globalConfig, setGlobalConfig } = useContext(context)
const { pandaRecordWebSocketRef, close } = props const { pandaRecordWebSocketRef, close } = props
const ulRef = useRef(null) const ulRef = useRef(null)
const directiveRef = useRef(null) const directiveRef = useRef(null)
const closeDirectiveRef = useRef(null)
const toolTipRef = useRef(null) const toolTipRef = useRef(null)
const timeRef = useRef(null) const timeRef = useRef(null)
const isDebug = globalConfig.get("isDebug") const isDebug = globalConfig.get("isDebug")
const currentDirectiveRef = useRef(null)
//是否开启系统语音
const isOpenSystemSound = globalConfig.getIn(['key', 'isOpenSystemSound'])
const [data, setData] = useState(() => [{ const [data, setData] = useState(() => [{
role: "system", role: "system",
...@@ -39,8 +44,12 @@ const Dialog = props => { ...@@ -39,8 +44,12 @@ const Dialog = props => {
sparkModelConfig: globalConfig.getIn(['key']).shortSound sparkModelConfig: globalConfig.getIn(['key']).shortSound
} }
}) })
closeDirectiveRef.current = new Directive({
directiveTypes: [CloseSessionDirective]
})
if (globalConfig.get('key').isOpenSparkModel) { if (globalConfig.get('key').isOpenSparkModel) {
directiveRef.current.directiveTypes.push(SparkDirective) directiveRef.current.directiveTypes.push(SparkDirective)
directiveRef.current._directiveTypes.push(SparkDirective)
} }
event.on("aiSound:finish", finish) event.on("aiSound:finish", finish)
event.on("aiSound:frame", frame) event.on("aiSound:frame", frame)
...@@ -53,11 +62,14 @@ const Dialog = props => { ...@@ -53,11 +62,14 @@ const Dialog = props => {
const finish = useCallback(async ({ resultText }) => { const finish = useCallback(async ({ resultText }) => {
if (!resultText) return if (!resultText) return
!isDebug && pandaRecordWebSocketRef.current.setStatus("pause") if (isOpenSystemSound) {
pandaRecordWebSocketRef.current && pandaRecordWebSocketRef.current.setStatus("pause")
}
const directive = directiveRef.current.parse({ const directive = directiveRef.current.parse({
text: resultText text: resultText
}) })
if (directive) { if (directive) {
currentDirectiveRef.current = directive
sendContent({ sendContent({
role: "system", role: "system",
content: "系统正在思考中,请稍后..." content: "系统正在思考中,请稍后..."
...@@ -71,20 +83,55 @@ const Dialog = props => { ...@@ -71,20 +83,55 @@ const Dialog = props => {
}) })
} }
}) })
!isDebug && pandaRecordWebSocketRef.current.setStatus("playing") if (isOpenSystemSound) {
pandaRecordWebSocketRef.current && pandaRecordWebSocketRef.current.setStatus("playing")
}
currentDirectiveRef.current = null
return return
} }
sendContent({ sendContent({
role: "system", role: "system",
content: "亲,我暂时还未理解你的意思,请换一种方式表达或者描述更加具体" content: "亲,我暂时还未理解你的意思,请换一种方式表达或者描述更加具体"
}) })
!isDebug && pandaRecordWebSocketRef.current.setStatus("playing") if (isOpenSystemSound) {
pandaRecordWebSocketRef.current && pandaRecordWebSocketRef.current.setStatus("playing")
}
}, []) }, [])
const frame = useCallback((data) => { const frame = useCallback((data) => {
const { resultText, resultTextTemp } = data const { resultText, resultTextTemp } = data
console.log(resultTextTemp) console.log(resultTextTemp)
if (!resultTextTemp) return if (!resultTextTemp) return
const hasCloseSessionDirective = closeDirectiveRef.current.parse({
text: resultTextTemp
})
!currentDirectiveRef.current && updateUserData({ resultTextTemp })
if (hasCloseSessionDirective) {
closeSession({
resultText: resultTextTemp
})
}
}, [])
const closeSession = ({ resultText }) => {
if (currentDirectiveRef.current) {
currentDirectiveRef.current.closeResponse()
pandaRecordWebSocketRef.current.wsClose()
pandaRecordWebSocketRef.current.setStatus("pause")
setTimeout(() => {
pandaRecordWebSocketRef.current.setStatus("playing")
}, 500)
} else {
if (!isDebug) {
pandaRecordWebSocketRef.current.wsClose()
event.emit("aiSound:finish", {
resultText
})
}
}
}
const updateUserData = ({ resultTextTemp }) => {
setData(data => { setData(data => {
const length = data.length const length = data.length
const lastData = data.at(-1) const lastData = data.at(-1)
...@@ -109,7 +156,7 @@ const Dialog = props => { ...@@ -109,7 +156,7 @@ const Dialog = props => {
}) })
} }
}) })
}, []) }
const updateLastData = ({ content, ...params }) => { const updateLastData = ({ content, ...params }) => {
setData(data => data.map((item, index) => { setData(data => data.map((item, index) => {
......
...@@ -17,6 +17,9 @@ const PandaTip = props => { ...@@ -17,6 +17,9 @@ const PandaTip = props => {
const timeRef = useRef(null) const timeRef = useRef(null)
const frame = useCallback(({ resultTextTemp }) => { const frame = useCallback(({ resultTextTemp }) => {
if(status == "close") {
console.log(resultTextTemp)
}
if (isDebug) return if (isDebug) return
const directive = directiveRef.current.parse({ const directive = directiveRef.current.parse({
text: resultTextTemp text: resultTextTemp
......
export default {
punctuationMark : "。,、;:?!”“,.!:"
}
\ No newline at end of file
...@@ -15,6 +15,10 @@ class BaseDirective { ...@@ -15,6 +15,10 @@ class BaseDirective {
}) { }) {
} }
closeResponse () {
}
} }
export default BaseDirective export default BaseDirective
\ No newline at end of file
import { store, event } from '@wisdom-utils/utils'; import { store, event } from '@wisdom-utils/utils';
import BaseDirective from '../BaseDirective'; import BaseDirective from '../BaseDirective';
import CloseSingleDirective from './CloseSingleDirective'; import CloseSingleDirective from './CloseSingleDirective';
import config from '../../config';
class CloseMenuDirective extends BaseDirective { class CloseMenuDirective extends BaseDirective {
static name = '关闭菜单或者模糊匹配关闭菜单'; static name = '关闭菜单或者模糊匹配关闭菜单';
...@@ -8,15 +9,15 @@ class CloseMenuDirective extends BaseDirective { ...@@ -8,15 +9,15 @@ class CloseMenuDirective extends BaseDirective {
match() { match() {
const { text } = this; const { text } = this;
let result = null; let result = null;
result = text.match(/关闭(所有).*(?=(?:,|,|。))/); result = new RegExp(`关闭(所有).*(?=(?:[${config.punctuationMark}]?))`)
if (!result) { if (!result) {
result = text.match(/关闭(当前).*(?=(?:,|,|。))/); result = new RegExp(`关闭(当前).*(?=(?:[${config.punctuationMark}]?))`)
} }
if (!result) { if (!result) {
result = text.match(/关闭(.*)(?=(?:菜单|功能|路径))/); result = text.match(/关闭(.*)(?=(?:菜单|功能|路径))/);
} }
if (!result) { if (!result) {
result = text.match(/关闭(.*)(?=(?:,|,|。))/); result = new RegExp(`关闭(.*)(?=(?:[${config.punctuationMark}]?))`)
} }
if (result && result.length >= 2 && !this.matchResult) { if (result && result.length >= 2 && !this.matchResult) {
this.matchResult = result[1]; this.matchResult = result[1];
......
...@@ -3,7 +3,7 @@ import BaseDirective from './BaseDirective' ...@@ -3,7 +3,7 @@ import BaseDirective from './BaseDirective'
class CloseSessionDirective extends BaseDirective { class CloseSessionDirective extends BaseDirective {
match (){ match (){
const {text} = this const {text} = this
if(/结束话/.test(text)) { if(/结束(.*)[的对]话/.test(text)) {
return true return true
} }
return false return false
......
...@@ -3,6 +3,7 @@ import { cut, extract } from '@congcongcai/jieba.js' ...@@ -3,6 +3,7 @@ import { cut, extract } from '@congcongcai/jieba.js'
import Utils from "../../utils/Utils"; import Utils from "../../utils/Utils";
import { uniq } from "lodash"; import { uniq } from "lodash";
import OpenSingleDirective from "./OpenSingleDirective"; import OpenSingleDirective from "./OpenSingleDirective";
import config from "../../config";
class OpenMenuDirective extends BaseDirective { class OpenMenuDirective extends BaseDirective {
static name="打开菜单或者模糊匹配打开菜单" static name="打开菜单或者模糊匹配打开菜单"
...@@ -14,7 +15,7 @@ class OpenMenuDirective extends BaseDirective { ...@@ -14,7 +15,7 @@ class OpenMenuDirective extends BaseDirective {
result = text.match(/打开(.*)(?=(?:菜单|功能|路径))/) result = text.match(/打开(.*)(?=(?:菜单|功能|路径))/)
} }
if (!result) { if (!result) {
result = text.match(/打开(.*)(?=(?:,|,|。))/) result = new RegExp(`打开(.*)(?=(?:[${config.punctuationMark}]?))`)
} }
if (result && result.length >= 2 && !this.matchResult) { if (result && result.length >= 2 && !this.matchResult) {
this.matchResult = result[1] this.matchResult = result[1]
......
import BaseDirective from "../BaseDirective";
class ServerDirective extends BaseDirective{
match () {
}
async excute ({
sendMsg = function () {}
}) {
}
}
export default ServerDirective
\ No newline at end of file
...@@ -18,17 +18,27 @@ class SparkDirective extends BaseDirective { ...@@ -18,17 +18,27 @@ class SparkDirective extends BaseDirective {
sendMsg = function () {} sendMsg = function () {}
}) { }) {
return new Promise(async (resolve, reject) => { return new Promise(async (resolve, reject) => {
this.resolve = resolve
this.sendMsg = sendMsg
const data = await this.pandaSparkWebSocket.sendMessag({ const data = await this.pandaSparkWebSocket.sendMessag({
content : this.text, content : this.text,
isLinkContext : false, isLinkContext : false,
frame ({resultTextTemp, resultText}) { frame ({resultTextTemp, resultText}) {
sendMsg(resultTextTemp) sendMsg?.(resultTextTemp)
} }
}) })
resolve(data.resultText) resolve(data.resultText)
}) })
} }
closeResponse() {
if(this.pandaSparkWebSocket) {
this.pandaSparkWebSocket.stop()
}
this.resolve("")
this.sendMsg = null
}
destroy(){ destroy(){
if(this.pandaSparkWebSocket) { if(this.pandaSparkWebSocket) {
this.pandaSparkWebSocket.destroy() this.pandaSparkWebSocket.destroy()
......
import BaseDirective from "./BaseDirective";
class TestDirective extends BaseDirective {
match () {
const {text} = this
if(/熊猫测试指令/.test(text)) {
return true
}
return false
}
async excute ({
sendMsg = function () {},
}) {
return new Promise((resolve , reject) => {
this.resolve = resolve
this.reject = reject
this.testCloseSession({sendMsg})
})
}
closeResponse () {
if(this.timer) {
clearInterval(this.timer)
this.timer = null
}
this.resolve && this.resolve()
}
testCloseSession({sendMsg}) {
this.timer = setInterval(() => {
sendMsg(parseInt(Math.random()* 10))
}, 100)
}
}
export default TestDirective
\ No newline at end of file
...@@ -3,13 +3,14 @@ import HomePageDirective from "./HomePageDirective" ...@@ -3,13 +3,14 @@ import HomePageDirective from "./HomePageDirective"
import CloseMenuDirective from "./CloseMenuDirective/index" import CloseMenuDirective from "./CloseMenuDirective/index"
import ByeDirective from "./ByeDirective" import ByeDirective from "./ByeDirective"
import OpenMenuDirective from "./OpenMenuDirective/index" import OpenMenuDirective from "./OpenMenuDirective/index"
import TestDirective from "./TestDirective"
const DirectiveTypes = [ const DirectiveTypes = (process.env.NODE_ENV == "development" ? [TestDirective] : []).concat([
AwakenDirective, // AwakenDirective,
HomePageDirective, HomePageDirective,
OpenMenuDirective, OpenMenuDirective,
CloseMenuDirective CloseMenuDirective
] ])
const AllDirectiveTypes = DirectiveTypes.concat(ByeDirective) const AllDirectiveTypes = DirectiveTypes.concat(ByeDirective)
class Directive { class Directive {
......
...@@ -6,6 +6,7 @@ import PandaSparkWebSocket from './core/sockets/PandaSparkWebSocket'; ...@@ -6,6 +6,7 @@ import PandaSparkWebSocket from './core/sockets/PandaSparkWebSocket';
import Directive , {DirectiveTypes, AllDirectiveTypes} from './directive'; import Directive , {DirectiveTypes, AllDirectiveTypes} from './directive';
import AwakenDirective from './directive/AwakenDirective'; import AwakenDirective from './directive/AwakenDirective';
import ByeDirective from './directive/ByeDirective'; import ByeDirective from './directive/ByeDirective';
import CloseSessionDirective from './directive/CloseSessionDirective';
export { export {
RecorderManager, RecorderManager,
...@@ -17,5 +18,6 @@ export { ...@@ -17,5 +18,6 @@ export {
AwakenDirective, AwakenDirective,
ByeDirective, ByeDirective,
DirectiveTypes, DirectiveTypes,
AllDirectiveTypes AllDirectiveTypes,
CloseSessionDirective
}; };
...@@ -24,7 +24,7 @@ const SoundAi = props => { ...@@ -24,7 +24,7 @@ const SoundAi = props => {
request("/PandaOMS/OMS/DataManger/GetDicConfigs", { request("/PandaOMS/OMS/DataManger/GetDicConfigs", {
params: { params: {
ParentName: "智能语音", ParentName: "智能语音",
ChilName: "是否开启,是否开启人机交互" ChilName: "是否开启,是否开启人机交互,是否开启系统语音"
} }
}).then(res => { }).then(res => {
if (res.code != 0) { if (res.code != 0) {
...@@ -42,17 +42,10 @@ const SoundAi = props => { ...@@ -42,17 +42,10 @@ const SoundAi = props => {
return return
} }
const spark = data.find(item => item.nodeName == "是否开启人机交互") const spark = data.find(item => item.nodeName == "是否开启人机交互")
if (spark && spark.nodeValue == "开") { keyRef.current['isOpenSparkModel'] = !!(spark && spark.nodeValue == "开")
setGlobalConfig(globalConfig => globalConfig.set("key", { const systemSound = data.find(item => item.nodeName == "是否开启系统语音")
...keyRef.current, keyRef.current['isOpenSystemSound'] = !!(systemSound && systemSound.nodeValue == "开")
isOpenSparkModel: true setGlobalConfig(globalConfig => globalConfig.set("key", {...keyRef.current}))
}))
} else {
setGlobalConfig(globalConfig => globalConfig.set("key", {
...keyRef.current,
isOpenSparkModel: false
}))
}
resolve() resolve()
}).catch(error => { }).catch(error => {
reject(error) reject(error)
......
import { event } from '@wisdom-utils/utils' import { event } from '@wisdom-utils/utils'
import { Utils } from './core' import { Utils , CloseSessionDirective , Directive } from './core'
const testText = text => const testText = text =>
new Promise((resolve, reject) => { new Promise((resolve, reject) => {
...@@ -20,13 +20,29 @@ const testText = text => ...@@ -20,13 +20,29 @@ const testText = text =>
const testFrameText = (text) => { const testFrameText = (text) => {
let timer = null , _text = "" , index = 0 let timer = null , _text = "" , index = 0
const closeSessionDirective = new Directive({
directiveTypes : [CloseSessionDirective]
})
return new Promise((resolve , reject) => { return new Promise((resolve , reject) => {
timer = setInterval(() => { timer = setInterval(() => {
_text += text.charAt(index) _text += text.charAt(index)
event.emit("aiSound:frame", { event.emit("aiSound:frame", {
resultTextTemp : _text resultTextTemp : _text
}) })
if(closeSessionDirective.parse({
text : _text
})) {
return testFinishText({resolve , text : _text , timer})
}
if(index == text.length) { if(index == text.length) {
return testFinishText({resolve , text, timer})
}
index++
}, 100)
})
}
const testFinishText = ({resolve , text , timer}) => {
clearInterval(timer) clearInterval(timer)
setTimeout(() => { setTimeout(() => {
event.emit('aiSound:finish', { event.emit('aiSound:finish', {
...@@ -34,10 +50,6 @@ const testFrameText = (text) => { ...@@ -34,10 +50,6 @@ const testFrameText = (text) => {
}); });
resolve() resolve()
}, 500) }, 500)
}
index++
}, 100)
})
} }
...@@ -49,7 +61,15 @@ const testCommand = async () => { ...@@ -49,7 +61,15 @@ const testCommand = async () => {
// await testText("打开顺平全景图菜单。") // await testText("打开顺平全景图菜单。")
// await testText("关闭全景图菜单。") // await testText("关闭全景图菜单。")
// await testText("关闭第1个。"); // await testText("关闭第1个。");
await testFrameText("打开熊猫智慧水务实景菜单。") // await testFrameText("打开铁山全景图菜单,结束对话,哈喽哈喽。")
// await testFrameText("我需要测试熊猫测试指令")
// await Utils.delayTime(5000)
// event.emit('aiSound:frame', {
// resultTextTemp: "打开铁山全景图菜单,结束对话,哈喽哈喽。",
// });
// await testFrameText("熊猫智慧水务解决方案是什么")
// await Utils.delayTime(6000)
// await testFrameText("打开场景搭建功能菜单")
} }
export default testCommand export default testCommand
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment