@onereach/step-voice
Version:
Onereach.ai Voice Steps
171 lines (170 loc) • 6.02 kB
JavaScript
"use strict";
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const step_1 = tslib_1.__importDefault(require("@onereach/flow-sdk/dst/step"));
class ConvStep extends step_1.default {
get cache() {
return this.convDataCache;
}
get conversation() {
if (this.data.conversation == null)
throw new Error('missing data.conversation');
return this.data.conversation;
}
get conversationId() {
const convOrName = this.conversation;
const conv = (typeof convOrName === 'string')
? this.config.mergeFields[convOrName] ?? convOrName
: convOrName;
if (conv.type === 'thread')
return this.dataThreadId;
if (typeof conv.name === 'string')
return conv.name;
if (typeof convOrName === 'string')
return convOrName;
throw new Error(`invalid conversation ${JSON.stringify(conv)}`);
}
get workerThreadId() {
return `G:${this.conversationId}`;
}
/** id of the thread where conversation data is stored */
get dataThreadId() {
const dataThreadId = this.state.thread ?? this.data.conversationThread;
return dataThreadId || this.thread.id;
}
get isGlobal() {
return false;
}
get isWorker() {
return this.thread.id === this.workerThreadId;
}
get useQueue() {
return true;
}
async fetchData() {
const data = await this._fetchCache();
if (data?._conv == null)
throw new Error(`missing conversation data in state ${this.state.name}`);
return data;
}
async getConversation() {
return (await this.fetchData())._conv;
}
async getConversationByName(conversation) {
const convDataThread = this.process.getSafeThread(this.dataThreadId);
return await convDataThread.get(conversation);
}
async updateData() {
if (this.convDataCache == null)
throw new Error(`missing conversation cache in state ${this.state.name}`);
// console.log('UPDATE', this.conversation, this.thread.id, this.step.label, this.convDataCache?._conv.que)
const convDataThread = this.process.getSafeThread(this.dataThreadId);
await convDataThread.set(this.conversation, this.convDataCache);
}
async hasConversation() {
return (await this._fetchCache())?._conv != null;
}
async runBefore() {
await super.runBefore();
this.log.debug('conv.runBefore', { state: this.state, conv: this.convDataCache?._conv });
if (this.thread.ending)
return;
// ensure cache is reset between step runs, just in case
this._clearCache();
if (!await this.hasConversation())
return;
if (this.state.direct)
return;
if (!this.event.processed && this.event.action && typeof this[this.event.action] === 'function') {
this.event.processed = true;
this.state.prevName = this.state.name;
this.state.name = this.event.action;
}
}
async onSkipEvent() {
this.log.debug('onSkipEvent');
this.state.name = this.state.prevSkipName;
delete this.state.prevSkipName;
}
async cancel() {
if (this.isGlobal) {
this.log.debug('conv.cannot cancel global');
}
}
async onCancel() {
// await this.popConvStep()
if (this.getExitStepId('cancel')) {
this.log.debug('conv.cancel exit');
this.exitStep('cancel');
}
else {
return await this.waitConvEnd();
}
}
async onSleep() {
// sleep
}
async onAwake() {
this.state.name = this.state.resumeState;
this.state.resumeState = undefined;
}
async onPause() {
this.state.resumeState = this.state.prevName;
this.state.prevName = undefined;
}
async onResume() {
this.state.name = this.state.resumeState;
this.state.resumeState = undefined;
}
async waitConvEnd() {
const workerThread = this.process.getThread(this.workerThreadId);
const workerState = workerThread?.state;
if (!this.isGlobal && this.thread.id !== 'main' && this.thread.id === workerState?.thread) {
this.log.debug('conv.wait for end', this.conversation);
this.gotoState({ ...this.state, name: this.waitGlobEnd.name, direct: true });
}
else {
this.log.debug('conv.end', this.conversation);
await this.onConvEnd();
}
}
async waitGlobEnd() {
const gcThreadId = this.workerThreadId;
// wait for glob thread end (if exists)
this.triggers.hook({ name: "end" /* ACTION.end */, thread: gcThreadId, times: 1 }, async () => await this.onConvEnd());
if (!this.process.getThread(gcThreadId))
await this.onConvEnd();
}
async onConvEnd() {
this.end();
}
async pause() {
}
async resume() {
}
async startConversation(data, { thread: _thread } = {}) {
this.convDataCache = {
...data,
_conv: data._conv ?? {}
};
await this.updateData();
// this.state.thread = this.dataThreadId
}
async _fetchCache() {
if (this.convDataCache != null)
return this.convDataCache;
const convDataThread = this.process.getSafeThread(this.dataThreadId);
this.convDataCache = await convDataThread.get(this.conversation);
// console.log('FETCH', this.conversation, this.thread.id, this.step.label, this.convDataCache?._conv.que)
return this.convDataCache;
}
_clearCache() {
this.convDataCache = undefined;
}
async _refreshCache() {
this._clearCache();
await this._fetchCache();
}
}
exports.default = ConvStep;