Commit 4b366d12 by Nick N. Sukharev

Изменён механизм построения доиалога с использованием модуля 'ext-parser'

1 parent 96285e28
Showing with 241 additions and 40 deletions
/*
* Модуль для сбора отладочных сообщений о вызове внешних функций
* и генерации диалогов из реплик, собранных во время разговора
*/
const dialogue_pauses = [
{
delay: -1000,
text: "!!! (перебивание разговора)"
},
{
delay: 2000,
text: "... (неловкая пауза)"
},
{
delay: 5000,
text: "... (МХАТовская пауза)"
},
{
delay: 8000,
text: "... (рекламная пауза Поле Чудес на первом канале)"
}
];
module.exports = exports = {
collect_msg(collection, event) {
if (event?.time === undefined) return;
if (event?.incoming === undefined) return;
if (event?.msg === undefined) return;
if (event?.msg?.msgId === undefined) return;
const msgId = event.msg.msgId;
if (msgId != "JobCommunicationMessage") return;
if (event?.msg?.content === undefined) return;
if (event?.msg?.content?.id === undefined) return;
if (event?.msg?.content?.type === undefined) return;
const content = event.msg.content;
const content_id = content.id;
const content_type = content.type;
const event_work = "work";
if (collection[content_id] === undefined) collection[content_id] = {};
switch (content_type) {
case "request":
const params = {};
for (const [param, value] of Object.entries(content.parameters)) {
const decoded = JSON.parse(value) ?? value;
params[param] = decoded;
}
collection[content_id][content_type] = {
time: event.time,
incoming: event.incoming,
method: content.method,
parameters: params
};
break
case "response":
const decoded = JSON.parse(content.result) ?? content.result;
collection[content_id][content_type] = {
time: event.time,
incoming: event.incoming,
result: decoded
};
const request = collection[content_id].request;
const startTime = (new Date(request.time)).getTime();
const finishTime = (new Date(event.time)).getTime();
collection[content_id][event_work] = {
start: request.time,
finish: event.time,
duration: (finishTime - startTime) / 1000
};
break
default:
break;
}
},
// Построение отчёта по вызовам внешних функций
build_graph_call_list(collection) {
const graph_calls = [];
let max_duration = 0;
for (const [id, event] of Object.entries(collection)) {
const entry = {
startTime: new Date(event.work.start),
endTime: new Date(event.work.finish),
duration: event.work.duration,
method: event.request.method,
parameters: event.request.parameters,
result: event.response.result
};
if (max_duration < event.work.duration)
max_duration = event.work.duration;
graph_calls.push(entry);
}
graph_calls.sort(function compare(a, b) {
a_start = a.startTime.getTime();
a_finish = a.endTime.getTime();
b_start = b.startTime.getTime();
b_finish = b.endTime.getTime();
if (a_start < b_start) return -1;
if (a_start > b_start) return 1;
if (a_finish < b_finish) return -1;
if (a_finish > b_finish) return 1;
return 0;
});
return {
max_duration: max_duration,
graph_calls: graph_calls
};
},
// Создание текста реплики диалога из объекта типа "transcription"
build_replic(ts, entry) {
rts = entry.startTime.getTime();
dts = rts - ts;
dts_m = Math.floor(dts / 60000);
dts_s = ((dts - (dts_m * 60000)) / 1000).toFixed(1);
if (dts_m < 10) dts_m = '0' + dts_m;
if (dts_s < 10) dts_s = '0' + dts_s;
hours = entry.startTime.getHours();
minutes = entry.startTime.getMinutes();
seconds = entry.startTime.getSeconds();
if (hours < 10) hours = '0' + hours;
if (minutes < 10) minutes = '0' + minutes;
if (seconds < 10) seconds = '0' + seconds;
speaker = entry.speaker;
if (speaker === "ai") speaker = " ai";
replic = speaker + ': [' + hours + ':' + minutes + ':' + seconds + ' '
+ dts_m + ':' + dts_s + '] - ' + entry.text + "\n";
return replic;
},
// Построение текста диалога из массива объектов типа "transcription"
build_dialogue_text (ts, replics) {
replics.sort(function compare(a, b) {
a_start = a.startTime.getTime();
a_finish = a.endTime.getTime();
b_start = b.startTime.getTime();
b_finish = b.endTime.getTime();
if (a_start < b_start) return -1;
if (a_start > b_start) return 1;
if (a_finish < b_finish) return -1;
if (a_finish > b_finish) return 1;
return 0;
});
let dialogue = "";
let interruption = false;
const replics_count = replics.length;
if (replics_count == 0) return {
interruption: interruption,
dialogue: dialogue
};
dialogue_pauses.sort(function compare(a, b) {
if (a.delay < b.delay) return -1;
if (a.delay > b.delay) return 1;
return 0;
});
let sys_msg = {
speaker: " sys",
text: "/ -=#=- /",
startTime: new Date(),
endTime: new Date()
};
var prev = replics[0];
dialogue = dialogue + this.build_replic(ts, prev);
for (var i = 1; i < replics_count; i ++) {
var entry = replics[i];
var prev_finish = prev.endTime.getTime();
var entry_start = entry.startTime.getTime();
var different = entry_start - prev_finish;
var j = dialogue_pauses.length;
while (j > 0) {
j --;
var pause = dialogue_pauses[j];
if ((j > 0) && (different > pause.delay)) {
sys_msg.startTime = new Date(prev_finish);
sys_msg.endTime = new Date(entry_start);
sys_msg.text = "/ " + pause.text + " /";
dialogue = dialogue + this.build_replic(ts, sys_msg);
break;
}
if ((j == 0) && (different < pause.delay)) {
sys_msg.startTime = new Date(entry_start);
sys_msg.endTime = new Date(prev_finish);
sys_msg.text = "/ " + pause.text + " /";
dialogue = dialogue + this.build_replic(ts, sys_msg);
if (entry.speaker == "ai") interruption = true;
else {
var entry_finish = entry.endTime.getTime();
if (entry_finish < prev_finish) interruption = true;
}
}
}
dialogue = dialogue + this.build_replic(ts, entry);
prev = entry;
}
return {
interruption: interruption,
dialogue: dialogue
};
}
};
......@@ -3,7 +3,8 @@ const AudioResources = require("./customTts.js");
const fs = require("fs");
const sys = require('child_process');
const shared = require("./shared");
const { exec } = require('child_process');
const ext_parser = require("./ext-parser");
const { exec } = require("child_process");
const local_num = "4077";
const events_owner = "198";
......@@ -145,6 +146,9 @@ async function main() {
return true;
});
const replics = [];
const collection = {};
await app.start();
let abonent_phone = process.argv[2] ?? "";
......@@ -234,26 +238,9 @@ async function main() {
await logFile.appendFile(logString);
conv.on("transcription", async (entry) => {
rts = entry.startTime.getTime();
dts = rts - ts;
dts_m = Math.floor(dts / 60000);
dts_s = ((dts - (dts_m * 60000)) / 1000).toFixed(1);
if (dts_m < 10) dts_m = '0' + dts_m;
if (dts_s < 10) dts_s = '0' + dts_s;
hours = entry.startTime.getHours();
minutes = entry.startTime.getMinutes();
seconds = entry.startTime.getSeconds();
if (hours < 10) hours = '0' + hours;
if (minutes < 10) minutes = '0' + minutes;
if (seconds < 10) seconds = '0' + seconds;
replics.push(entry);
replic = ext_parser.build_replic(ts, entry);
speaker = entry.speaker;
if (speaker === "ai") speaker = " ai";
replic = speaker + ': [' + hours + ':' + minutes + ':' + seconds + ' '
+ dts_m + ':' + dts_s + '] - ' + entry.text + "\n";
txtData = txtData + replic;
await txtFile.appendFile(replic);
await logFile.appendFile(replic);
......@@ -264,6 +251,8 @@ async function main() {
});
conv.on("debugLog", async (event) => {
if (event?.msg?.msgId === "JobCommunicationMessage")
ext_parser.collect_msg(collection, event);
if (event?.msg?.msgId === "RecognizedSpeechMessage") {
const logEntry = event?.msg?.results[0]?.facts;
await logFile.appendFile(JSON.stringify(logEntry, undefined, 2) + "\n");
......@@ -280,21 +269,6 @@ async function main() {
const result = await conv.execute();
let close_time = new Date();
rts = close_time.getTime();
dts = rts - ts;
dts_m = Math.floor(dts / 60000);
dts_s = ((dts - (dts_m * 60000)) / 1000).toFixed(1);
if (dts_m < 10) dts_m = '0' + dts_m;
if (dts_s < 10) dts_s = '0' + dts_s;
hours = close_time.getHours();
minutes = close_time.getMinutes();
seconds = close_time.getSeconds();
if (hours < 10) hours = '0' + hours;
if (minutes < 10) minutes = '0' + minutes;
if (seconds < 10) seconds = '0' + seconds;
const conversations_statuses = {
normal: "разговор завершён",
broken: "абонент повесил трубку",
......@@ -307,9 +281,21 @@ async function main() {
conversation_status_id = "unknown";
conversation_status = "Не определённое в сценанрии завершение разговора";
}
speaker = " sys";
replic = speaker + ': [' + hours + ':' + minutes + ':' + seconds + ' '
+ dts_m + ':' + dts_s + "] - / " + conversation_status + " /\n";
const dialogue_info = ext_parser.build_dialogue_text(ts, replics);
const graph_calls_list = ext_parser.build_graph_call_list(collection);
txtData = txtData + dialogue_info.dialogue;
result.output.dialogue_interruption = dialogue_info.interruption;
result.output.graph_call_max_duration = graph_calls_list.max_duration;
result.output.graph_calls = graph_calls_list.graph_calls;
entry = {
speaker: " sys",
text: "/ " + conversation_status + " /",
startTime: new Date(),
endTime: new Date()
};
replic = ext_parser.build_replic(ts, entry);
txtData = txtData + replic;
await txtFile.appendFile(replic);
......@@ -363,10 +349,11 @@ async function main() {
// dst: local_num,
dst: caller_phone,
src: local_num,
duration: Math.ceil((conv_stop - conv_start)/1000),
duration: Math.ceil((result.tracking[''].blockDuration)/1000),
billsec: Math.ceil((result.duration)/1000),
direction: "output",
billsec: Math.ceil((conv_stop - conv_begin)/1000),
app_name: conv_info.app_name,
app_name_full: conv_info.app_name_full,
app_id: conv_info.app_id,
......
Markdown is supported
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!