@cognigy/rest-api-client 0.13.2 → 0.14.0
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.
- package/CHANGELOG.md +5 -1
- package/build/apigroups/ResourcesAPIGroup_2_0.js +15 -3
- package/build/shared/charts/descriptors/apps/setHtmlAppState.js +83 -13
- package/build/shared/charts/descriptors/connectionNodes/generativeAIProviders/azureOpenAIProviderConnection.js +14 -0
- package/build/shared/charts/descriptors/connectionNodes/generativeAIProviders/index.js +19 -0
- package/build/shared/charts/descriptors/connectionNodes/generativeAIProviders/openAIProviderConnection.js +11 -0
- package/build/shared/charts/descriptors/index.js +8 -5
- package/build/shared/charts/descriptors/message/question/optionalQuestion.js +22 -6
- package/build/shared/charts/descriptors/message/question/question.js +193 -25
- package/build/shared/charts/descriptors/message/say.js +33 -2
- package/build/shared/charts/descriptors/service/completeText.js +316 -0
- package/build/shared/charts/descriptors/service/handoverV2.js +47 -1
- package/build/shared/charts/descriptors/service/index.js +3 -1
- package/build/shared/charts/descriptors/voice/mappers/setSessionConfig.mapper.js +40 -7
- package/build/shared/charts/descriptors/voice/mappers/transfer.mapper.js +93 -32
- package/build/shared/charts/descriptors/voice/nodes/play.js +8 -6
- package/build/shared/charts/descriptors/voice/nodes/sessionSpeechParameters.js +90 -8
- package/build/shared/charts/descriptors/voice/nodes/transfer.js +2 -2
- package/build/shared/charts/descriptors/voice/utils/helper.js +11 -1
- package/build/shared/charts/descriptors/voicegateway/nodes/agentAssist.js +2 -2
- package/build/shared/charts/descriptors/voicegateway2/nodes/play.js +4 -1
- package/build/shared/charts/descriptors/voicegateway2/nodes/refer.js +3 -3
- package/build/shared/charts/descriptors/voicegateway2/nodes/setSessionConfig.js +125 -26
- package/build/shared/charts/descriptors/voicegateway2/nodes/transfer.js +91 -7
- package/build/shared/charts/descriptors/voicegateway2/utils/helper.js +18 -11
- package/build/shared/charts/descriptors/voicegateway2/utils/strip-nulls.js +4 -1
- package/build/shared/charts/helpers/generativeAI/getRephraseWithAIFields.js +100 -0
- package/build/shared/charts/helpers/generativeAI/rephraseSentenceWithAi.js +44 -0
- package/build/shared/constants.js +2 -1
- package/build/shared/interfaces/ai.js +16 -0
- package/build/shared/interfaces/analytics/IAnalyticsDataGoals.js +3 -0
- package/build/shared/interfaces/endpointInterface.js +1 -0
- package/build/shared/interfaces/filemanager/IRuntimeFile.js +30 -0
- package/build/shared/interfaces/filemanager/index.js +1 -0
- package/build/shared/interfaces/handover.js +39 -3
- package/build/shared/interfaces/messageAPI/endpoints.js +2 -0
- package/build/shared/interfaces/messageAPI/handover.js +6 -0
- package/build/shared/interfaces/resources/IConnectionSchema.js +2 -1
- package/build/shared/interfaces/resources/IExtension.js +2 -1
- package/build/shared/interfaces/resources/IFlow.js +2 -1
- package/build/shared/interfaces/resources/ILexicon.js +15 -2
- package/build/shared/interfaces/resources/INodeDescriptorSet.js +1 -1
- package/build/shared/interfaces/resources/intent/IIntent.js +5 -2
- package/build/shared/interfaces/resources/intent/IIntentRelation.js +3 -1
- package/build/shared/interfaces/resources/settings/IAgentSettings.js +9 -4
- package/build/shared/interfaces/resources/settings/IGenerativeAISettings.js +136 -0
- package/build/shared/interfaces/resources/settings/index.js +7 -1
- package/build/shared/interfaces/restAPI/resources/flow/v2.0/sentence/IGenerateSentencesRest_2_0.js +3 -0
- package/package.json +1 -1
- package/types/index.d.ts +569 -184
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* 5.2.4 Sets itself as the next Node and stops execution
|
|
32
32
|
*/
|
|
33
33
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
34
|
-
exports.QUESTION = void 0;
|
|
34
|
+
exports.QUESTION = exports.QuestionTypes = void 0;
|
|
35
35
|
//#region Imports
|
|
36
36
|
/* Custom modules */
|
|
37
37
|
const createNodeDescriptor_1 = require("../../../createNodeDescriptor");
|
|
@@ -48,6 +48,26 @@ const service_1 = require("../../service");
|
|
|
48
48
|
const datepickerUtils_1 = require("./utils/datepickerUtils");
|
|
49
49
|
const resetNodeState_1 = require("./utils/resetNodeState");
|
|
50
50
|
const questionHandover_1 = require("./utils/questionHandover");
|
|
51
|
+
const getRephraseWithAIFields_1 = require("../../../helpers/generativeAI/getRephraseWithAIFields");
|
|
52
|
+
var QuestionTypes;
|
|
53
|
+
(function (QuestionTypes) {
|
|
54
|
+
QuestionTypes[QuestionTypes["date"] = 0] = "date";
|
|
55
|
+
QuestionTypes[QuestionTypes["keyphrase"] = 1] = "keyphrase";
|
|
56
|
+
QuestionTypes[QuestionTypes["regex"] = 2] = "regex";
|
|
57
|
+
QuestionTypes[QuestionTypes["email"] = 3] = "email";
|
|
58
|
+
QuestionTypes[QuestionTypes["number"] = 4] = "number";
|
|
59
|
+
QuestionTypes[QuestionTypes["temperature"] = 5] = "temperature";
|
|
60
|
+
QuestionTypes[QuestionTypes["age"] = 6] = "age";
|
|
61
|
+
QuestionTypes[QuestionTypes["duration"] = 7] = "duration";
|
|
62
|
+
QuestionTypes[QuestionTypes["yesNo"] = 8] = "yesNo";
|
|
63
|
+
QuestionTypes[QuestionTypes["text"] = 9] = "text";
|
|
64
|
+
QuestionTypes[QuestionTypes["money"] = 10] = "money";
|
|
65
|
+
QuestionTypes[QuestionTypes["percentage"] = 11] = "percentage";
|
|
66
|
+
QuestionTypes[QuestionTypes["intent"] = 12] = "intent";
|
|
67
|
+
QuestionTypes[QuestionTypes["data"] = 13] = "data";
|
|
68
|
+
QuestionTypes[QuestionTypes["url"] = 14] = "url";
|
|
69
|
+
QuestionTypes[QuestionTypes["custom"] = 15] = "custom";
|
|
70
|
+
})(QuestionTypes = exports.QuestionTypes || (exports.QuestionTypes = {}));
|
|
51
71
|
//#endregion Interfaces
|
|
52
72
|
exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
53
73
|
//#region DescriptorFields
|
|
@@ -595,6 +615,48 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
595
615
|
value: "handover"
|
|
596
616
|
}
|
|
597
617
|
},
|
|
618
|
+
{
|
|
619
|
+
key: "escaleAnswersHandoverEightByEightChannelId",
|
|
620
|
+
type: "cognigyText",
|
|
621
|
+
label: "8x8 Channel Id",
|
|
622
|
+
description: "The 8x8 Channel Id",
|
|
623
|
+
condition: {
|
|
624
|
+
key: "escalateAnswersAction",
|
|
625
|
+
value: "handover"
|
|
626
|
+
}
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
key: "escalateAnswersHandoverEightByEightQueueId",
|
|
630
|
+
type: "cognigyText",
|
|
631
|
+
label: "8x8 Queue Id",
|
|
632
|
+
description: "The 8x8 Queue Id",
|
|
633
|
+
condition: {
|
|
634
|
+
key: "escalateAnswersAction",
|
|
635
|
+
value: "handover"
|
|
636
|
+
}
|
|
637
|
+
},
|
|
638
|
+
{
|
|
639
|
+
key: "escalateAnswersHandoverEightByEightJSONProps",
|
|
640
|
+
type: "json",
|
|
641
|
+
label: "8x8 JSON Properties",
|
|
642
|
+
description: "The 8x8 JSON Properties",
|
|
643
|
+
defaultValue: [],
|
|
644
|
+
condition: {
|
|
645
|
+
key: "escalateAnswersAction",
|
|
646
|
+
value: "handover"
|
|
647
|
+
}
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
key: "escalateAnswersHandoverAdditionalCategoryIds",
|
|
651
|
+
type: "cognigyTextArray",
|
|
652
|
+
label: "Additional Category Ids",
|
|
653
|
+
description: "Additional Category Ids to be passed to Ring Central Engage handover provider",
|
|
654
|
+
defaultValue: [],
|
|
655
|
+
condition: {
|
|
656
|
+
key: "escalateAnswersAction",
|
|
657
|
+
value: "handover"
|
|
658
|
+
}
|
|
659
|
+
},
|
|
598
660
|
{
|
|
599
661
|
key: "escalateAnswersOnce",
|
|
600
662
|
type: "toggle",
|
|
@@ -897,6 +959,48 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
897
959
|
value: "handover"
|
|
898
960
|
}
|
|
899
961
|
},
|
|
962
|
+
{
|
|
963
|
+
key: "escalateIntentsHandoverEightByEightChannelId",
|
|
964
|
+
type: "cognigyText",
|
|
965
|
+
label: "8x8 Channel Id",
|
|
966
|
+
description: "Channel Id in 8x8",
|
|
967
|
+
condition: {
|
|
968
|
+
key: "escalateIntentsAction",
|
|
969
|
+
value: "handover"
|
|
970
|
+
}
|
|
971
|
+
},
|
|
972
|
+
{
|
|
973
|
+
key: "escalateIntentsHandoverEightByEightQueueId",
|
|
974
|
+
type: "cognigyText",
|
|
975
|
+
label: "8x8 Queue Id",
|
|
976
|
+
description: "Queue Id in 8x8",
|
|
977
|
+
condition: {
|
|
978
|
+
key: "escalateIntentsAction",
|
|
979
|
+
value: "handover"
|
|
980
|
+
}
|
|
981
|
+
},
|
|
982
|
+
{
|
|
983
|
+
key: "escalateIntentsHandoverEightByEightJSONProps",
|
|
984
|
+
type: "json",
|
|
985
|
+
label: "8x8 JSON Properties",
|
|
986
|
+
description: "JSON Properties in 8x8",
|
|
987
|
+
defaultValue: [],
|
|
988
|
+
condition: {
|
|
989
|
+
key: "escalateIntentsAction",
|
|
990
|
+
value: "handover"
|
|
991
|
+
}
|
|
992
|
+
},
|
|
993
|
+
{
|
|
994
|
+
key: "escalateIntentsHandoverAdditionalCategoryIds",
|
|
995
|
+
type: "cognigyTextArray",
|
|
996
|
+
label: "Additional Category Ids",
|
|
997
|
+
description: "Additional Category Ids to be passed to Ring Central Engage handover provider",
|
|
998
|
+
defaultValue: [],
|
|
999
|
+
condition: {
|
|
1000
|
+
key: "escalateIntentsAction",
|
|
1001
|
+
value: "handover"
|
|
1002
|
+
}
|
|
1003
|
+
},
|
|
900
1004
|
{
|
|
901
1005
|
key: "escalateIntentsRepromptPrevention",
|
|
902
1006
|
type: "toggle",
|
|
@@ -951,7 +1055,8 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
951
1055
|
...(0, datepickerUtils_1.getDatePickerFields)({
|
|
952
1056
|
"key": "type",
|
|
953
1057
|
"value": "date"
|
|
954
|
-
})
|
|
1058
|
+
}),
|
|
1059
|
+
...(0, getRephraseWithAIFields_1.getRephraseWithAIFields)(),
|
|
955
1060
|
].filter(field => !!field),
|
|
956
1061
|
sections: [
|
|
957
1062
|
{
|
|
@@ -1007,6 +1112,7 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1007
1112
|
"escalateIntentsHandoverQuickReply",
|
|
1008
1113
|
"escalateIntentsHandoverResolveBehavior",
|
|
1009
1114
|
"escalateIntentsHandoverSendResolveEvent",
|
|
1115
|
+
"escalateIntentsHandoverAdditionalCategoryIds",
|
|
1010
1116
|
process.env.FEATURE_USE_COGNIGY_LIVE_AGENT && "escalateIntentsHandoverLiveAgentInboxId",
|
|
1011
1117
|
process.env.FEATURE_USE_COGNIGY_LIVE_AGENT && "escalateIntentsAgentAssistInitMessage",
|
|
1012
1118
|
process.env.FEATURE_USE_COGNIGY_LIVE_AGENT && "escalateIntentsAllowAgentInject",
|
|
@@ -1014,6 +1120,9 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1014
1120
|
"escalateIntentHandoverSendTranscriptAsFirstMessage",
|
|
1015
1121
|
"escalateIntentsHandoverSalesforcePrechatEntities",
|
|
1016
1122
|
"escalateIntentsHandoverSalesforcePrechatDetails",
|
|
1123
|
+
"escalateIntentsHandoverEightByEightChannelId",
|
|
1124
|
+
"escalateIntentsHandoverEightByEightQueueId",
|
|
1125
|
+
"escalateIntentsHandoverEightByEightJSONProps",
|
|
1017
1126
|
"escalateIntentsRepromptPrevention"
|
|
1018
1127
|
].filter(field => !!field)
|
|
1019
1128
|
},
|
|
@@ -1036,6 +1145,7 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1036
1145
|
"escalateAnswersHandoverQuickReply",
|
|
1037
1146
|
"escalateAnswersHandoverResolveBehavior",
|
|
1038
1147
|
"escalateAnswersHandoverSendResolveEvent",
|
|
1148
|
+
"escalateAnswersHandoverAdditionalCategoryIds",
|
|
1039
1149
|
process.env.FEATURE_USE_COGNIGY_LIVE_AGENT && "escalateAnswersHandoverLiveAgentInboxId",
|
|
1040
1150
|
process.env.FEATURE_USE_COGNIGY_LIVE_AGENT && "escalateAnswersAgentAssistInitMessage",
|
|
1041
1151
|
process.env.FEATURE_USE_COGNIGY_LIVE_AGENT && "escalateAnswersAllowAgentInject",
|
|
@@ -1043,6 +1153,9 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1043
1153
|
"escalateAnswersHandoverSendTranscriptAsFirstMessage",
|
|
1044
1154
|
"escalateAnswersHandoverSalesforcePrechatEntities",
|
|
1045
1155
|
"escalateAnswersHandoverSalesforcePrechatDetails",
|
|
1156
|
+
"escalateAnswersHandoverEightByEightChannelId",
|
|
1157
|
+
"escalateAnswersHandoverEightByEightQueueId",
|
|
1158
|
+
"escalateAnswersHandoverEightByEightJSONProps",
|
|
1046
1159
|
"escalateAnswersRepromptPrevention",
|
|
1047
1160
|
"escalateAnswersOnce",
|
|
1048
1161
|
].filter(field => !!field)
|
|
@@ -1063,8 +1176,9 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1063
1176
|
...(0, datepickerUtils_1.getDatePickerSections)("Datepicker - ", {
|
|
1064
1177
|
"key": "type",
|
|
1065
1178
|
"value": "date"
|
|
1066
|
-
})
|
|
1067
|
-
|
|
1179
|
+
}),
|
|
1180
|
+
(0, getRephraseWithAIFields_1.getRephraseWithAISection)(),
|
|
1181
|
+
].filter(section => !!section),
|
|
1068
1182
|
form: [
|
|
1069
1183
|
{ type: "field", key: "type" },
|
|
1070
1184
|
{ type: "field", key: "keyphraseTag" },
|
|
@@ -1083,7 +1197,8 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1083
1197
|
{ type: "section", key: "datepicker_datesettings" },
|
|
1084
1198
|
{ type: "section", key: "datepicker_timesettings" },
|
|
1085
1199
|
{ type: "section", key: "datepicker_enableDisable" },
|
|
1086
|
-
{ type: "section", key: "datepicker_advanced" }
|
|
1200
|
+
{ type: "section", key: "datepicker_advanced" },
|
|
1201
|
+
{ type: "section", key: "aiEnhancedOutput" },
|
|
1087
1202
|
],
|
|
1088
1203
|
preview: {
|
|
1089
1204
|
key: "say",
|
|
@@ -1091,10 +1206,20 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1091
1206
|
},
|
|
1092
1207
|
tags: ["basic", "message", "nlu"],
|
|
1093
1208
|
//#endregion DescriptorFields
|
|
1094
|
-
function: async ({ cognigy, nodeId, config, inputOptions }) => {
|
|
1209
|
+
function: async ({ cognigy, nodeId, organisationId, config, inputOptions }) => {
|
|
1095
1210
|
var _a;
|
|
1096
|
-
const { say, type, validationMessage, validationRepeat, storeResultInContext, contextKey, storeInContactProfile, profileKey, storeDetailedResults, parseResultOnEntry, repromptCondition, maxExecutionDiff, resultLocation, skipRepromptOnIntent, onlyAcceptEscalationIntents, escalateAnswersAction, escalateAnswersThreshold, escalateAnswersGotoTarget, escalateAnswersExecuteTarget, escalateAnswersGotoExecutionMode, escalateAnswersInjectedText, escalateAnswersInjectedData, escalateAnswersMessage, escalateAnswersRepromptPrevention, escalateAnswersOnce, escalateAnswersHandoverText, escalateAnswersRepeatHandoverMessage, escalateAnswersHandoverCancelIntent, escalateAnswersHandoverQuickReply, escalateAnswersHandoverChatwootInboxId, escalateAnswersHandoverLiveAgentInboxId, escalateAnswersHandoverSendTranscriptAsFirstMessage, escalateAnswersHandoverSalesforcePrechatEntities, escalateAnswersHandoverSalesforcePrechatDetails, escalateAnswersHandoverSendResolveEvent, escalateAnswersHandoverResolveBehavior, escalateAnswersAgentAssistInitMessage, escalateAnswersAllowAgentInject, escalateIntentsAction, escalateIntentsValidIntents, escalateIntentsThreshold, escalateIntentsGotoTarget, escalateIntentsExecuteTarget, escalateIntentsGotoExecutionMode, escalateIntentsInjectedText, escalateIntentsInjectedData, escalateIntentsMessage, escalateIntentsHandoverText, escalateIntentsRepeatHandoverMessage, escalateIntentsHandoverCancelIntent, escalateIntentsHandoverQuickReply, escalateIntentsHandoverChatwootInboxId, escalateIntentsHandoverLiveAgentInboxId, escalateIntentHandoverSendTranscriptAsFirstMessage, escalateIntentsHandoverSalesforcePrechatEntities, escalateIntentsHandoverSalesforcePrechatDetails, escalateIntentsRepromptPrevention, escalateIntentsHandoverSendResolveEvent, escalateIntentsHandoverResolveBehavior, escalateIntentsAgentAssistInitMessage, escalateIntentsAllowAgentInject, reconfirmationBehaviour, reconfirmationQuestion, reconfirmationQuestionReprompt } = config;
|
|
1211
|
+
const { say, type, validationMessage, validationRepeat, storeResultInContext, contextKey, storeInContactProfile, profileKey, storeDetailedResults, parseResultOnEntry, repromptCondition, maxExecutionDiff, resultLocation, skipRepromptOnIntent, onlyAcceptEscalationIntents, escalateAnswersAction, escalateAnswersThreshold, escalateAnswersGotoTarget, escalateAnswersExecuteTarget, escalateAnswersGotoExecutionMode, escalateAnswersInjectedText, escalateAnswersInjectedData, escalateAnswersMessage, escalateAnswersRepromptPrevention, escalateAnswersOnce, escalateAnswersHandoverText, escalateAnswersRepeatHandoverMessage, escalateAnswersHandoverCancelIntent, escalateAnswersHandoverQuickReply, escalateAnswersHandoverChatwootInboxId, escalateAnswersHandoverLiveAgentInboxId, escalateAnswersHandoverAdditionalCategoryIds, escalateAnswersHandoverSendTranscriptAsFirstMessage, escalateAnswersHandoverSalesforcePrechatEntities, escalateAnswersHandoverSalesforcePrechatDetails, escalateAnswersHandoverEightByEightChannelId, escalateAnswersHandoverEightByEightQueueId, escalateAnswersHandoverEightByEightJSONProps, escalateAnswersHandoverSendResolveEvent, escalateAnswersHandoverResolveBehavior, escalateAnswersAgentAssistInitMessage, escalateAnswersAllowAgentInject, escalateIntentsAction, escalateIntentsValidIntents, escalateIntentsThreshold, escalateIntentsGotoTarget, escalateIntentsExecuteTarget, escalateIntentsGotoExecutionMode, escalateIntentsInjectedText, escalateIntentsInjectedData, escalateIntentsMessage, escalateIntentsHandoverText, escalateIntentsRepeatHandoverMessage, escalateIntentsHandoverCancelIntent, escalateIntentsHandoverQuickReply, escalateIntentsHandoverChatwootInboxId, escalateIntentsHandoverLiveAgentInboxId, escalateIntentsHandoverAdditionalCategoryIds, escalateIntentHandoverSendTranscriptAsFirstMessage, escalateIntentsHandoverSalesforcePrechatEntities, escalateIntentsHandoverSalesforcePrechatDetails, escalateIntentsHandoverEightByEightChannelId, escalateIntentsHandoverEightByEightQueueId, escalateIntentsHandoverEightByEightJSONProps, escalateIntentsRepromptPrevention, escalateIntentsHandoverSendResolveEvent, escalateIntentsHandoverResolveBehavior, escalateIntentsAgentAssistInitMessage, escalateIntentsAllowAgentInject, reconfirmationBehaviour, reconfirmationQuestion, reconfirmationQuestionReprompt } = config;
|
|
1097
1212
|
const { input, context, profile, api } = cognigy;
|
|
1213
|
+
const rephraseWithAIParams = {
|
|
1214
|
+
generativeAI_rephraseOutputMode: config.generativeAI_rephraseOutputMode,
|
|
1215
|
+
generativeAI_temperature: config.generativeAI_temperature,
|
|
1216
|
+
generativeAI_amountOfLastUserInputs: config.generativeAI_amountOfLastUserInputs,
|
|
1217
|
+
generativeAI_customInputs: config.generativeAI_customInputs,
|
|
1218
|
+
promtType: undefined,
|
|
1219
|
+
questionType: undefined,
|
|
1220
|
+
question: undefined,
|
|
1221
|
+
answer: undefined,
|
|
1222
|
+
};
|
|
1098
1223
|
const activeQuestionHandover = api.getSystemContext(`question-handover-${nodeId}`);
|
|
1099
1224
|
const hasHandoverCompleted = !!activeQuestionHandover && ((_a = input.handover) === null || _a === void 0 ? void 0 : _a.status) !== "agentInject";
|
|
1100
1225
|
const shouldEntrypointReset = activeQuestionHandover === null || activeQuestionHandover === void 0 ? void 0 : activeQuestionHandover.resetEntrypoint;
|
|
@@ -1102,6 +1227,11 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1102
1227
|
(0, resetNodeState_1.resetNodeState)(api, nodeId);
|
|
1103
1228
|
return;
|
|
1104
1229
|
}
|
|
1230
|
+
// if we're in a subsequent execution or we want to parse results
|
|
1231
|
+
// immediately on entry, continue with evaluation
|
|
1232
|
+
let result = (0, evaluateQuestionAnswer_1.evaluateQuestionAnswer)({ cognigy, config });
|
|
1233
|
+
// Verify that answer is valid based on some other conditions defined in the function
|
|
1234
|
+
const isValid = (0, validateQuestionAnswer_1.validateQuestionAnswer)(cognigy, config);
|
|
1105
1235
|
// compute how often this node was hit
|
|
1106
1236
|
const executionAmount = api.getExecutionAmount(nodeId);
|
|
1107
1237
|
// compute how long ago this node was hit
|
|
@@ -1144,6 +1274,7 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1144
1274
|
}
|
|
1145
1275
|
});
|
|
1146
1276
|
const restoredInput = api.getSystemContext("reconfirmationQuestionInput");
|
|
1277
|
+
// Copy specific data of previous input into the current input
|
|
1147
1278
|
input.intent = restoredInput.intent;
|
|
1148
1279
|
input.intentScore = restoredInput.intentScore;
|
|
1149
1280
|
input.intentFlow = restoredInput.intentFlow;
|
|
@@ -1151,20 +1282,30 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1151
1282
|
input.intentLevel = restoredInput.intentLevel;
|
|
1152
1283
|
if (res === true) { // the reconfirmation answer was yes-like
|
|
1153
1284
|
// get the tentative answer that was given and store it
|
|
1154
|
-
const
|
|
1155
|
-
(0, storeQuestionAnswer_1.storeQuestionAnswer)({ context, contextKey, input, result, storeResultInContext });
|
|
1285
|
+
const activeQuestionResult = activeQuestion === null || activeQuestion === void 0 ? void 0 : activeQuestion.tentativeAnswer;
|
|
1286
|
+
(0, storeQuestionAnswer_1.storeQuestionAnswer)({ context, contextKey, input, result: activeQuestionResult, storeResultInContext });
|
|
1156
1287
|
// reset everything and continue to the next node
|
|
1157
1288
|
(0, resetNodeState_1.resetNodeState)(api, nodeId);
|
|
1158
1289
|
return;
|
|
1159
1290
|
}
|
|
1160
1291
|
else if (res !== false) { // the reconfirmation answer was invalid (e.g. no yes-like or no-like answer)
|
|
1292
|
+
if (result !== null && result !== undefined && isValid) {
|
|
1293
|
+
// we need to store the updated input, to be able to restore it afterwards. If we don't do this, then we
|
|
1294
|
+
// will lose data of the current input that was sent by the user. This could happen when the setting
|
|
1295
|
+
// "Skip if Answer in Input" is enabled and updated information is sent instead of saying "yes" or "no".
|
|
1296
|
+
api.setSystemContext("reconfirmationQuestionInput", input);
|
|
1297
|
+
// remember the given answer in the activeQuestion object
|
|
1298
|
+
activeQuestion.tentativeAnswer = result;
|
|
1299
|
+
// remember a shortform of the given answer in the activeQuestion object
|
|
1300
|
+
activeQuestion.tentativeAnswerShortform = (0, generateAnswerShortForm_1.generateAnswerShortForm)(type, result, cognigy.input.text);
|
|
1301
|
+
}
|
|
1161
1302
|
// output reconfirmation reprompt
|
|
1162
1303
|
if (reconfirmationQuestionReprompt) {
|
|
1163
|
-
say_1.SAY.function({ cognigy, childConfigs: [], nodeId, config: { say: { type: "text", text: [reconfirmationQuestionReprompt] } } });
|
|
1304
|
+
await say_1.SAY.function({ cognigy, childConfigs: [], nodeId, organisationId, config: { say: { type: "text", text: [reconfirmationQuestionReprompt] } } });
|
|
1164
1305
|
}
|
|
1165
1306
|
// output reconfirmationQuestion
|
|
1166
1307
|
const tentativeAnswerShortform = (activeQuestion === null || activeQuestion === void 0 ? void 0 : activeQuestion.tentativeAnswerShortform) || "";
|
|
1167
|
-
say_1.SAY.function({ cognigy, childConfigs: [], nodeId, config: { say: { type: "text", text: [reconfirmationQuestion.replace("[ANSWER]", tentativeAnswerShortform)] } } });
|
|
1308
|
+
await say_1.SAY.function({ cognigy, childConfigs: [], nodeId, organisationId, config: { say: { type: "text", text: [reconfirmationQuestion.replace("[ANSWER]", tentativeAnswerShortform)] } } });
|
|
1168
1309
|
// set myself as next node and stop
|
|
1169
1310
|
api.setNextNode(nodeId);
|
|
1170
1311
|
api.stopExecution();
|
|
@@ -1172,7 +1313,12 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1172
1313
|
}
|
|
1173
1314
|
else { // the reconfirmation answer was no-like
|
|
1174
1315
|
// delete all remnants of this reconfirmation
|
|
1175
|
-
|
|
1316
|
+
// Do not delete the "activeQuestion" when there is a reconfirmation process in progress. Otherwise, we
|
|
1317
|
+
// would lose activeQuestion.tentativeAnswer when the reconfirmation succeeds with "yes". The result would
|
|
1318
|
+
// then be empty.
|
|
1319
|
+
if (!(result !== null && result !== undefined && isValid)) {
|
|
1320
|
+
api.deleteSystemContext('activeQuestion');
|
|
1321
|
+
}
|
|
1176
1322
|
api.deleteSystemContext('reconfirmationQuestionInProgress');
|
|
1177
1323
|
api.deleteSystemContext("reconfirmationQuestionInput");
|
|
1178
1324
|
// pretend the question was never asked and continue
|
|
@@ -1222,7 +1368,9 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1222
1368
|
// #region 2 FirstTimeNodeIsHit
|
|
1223
1369
|
// if it's the first execution and you don't force evaluation on first execution, ask the question
|
|
1224
1370
|
if (isFirstExecution && !parseResultOnEntry) {
|
|
1225
|
-
|
|
1371
|
+
rephraseWithAIParams.promtType = "question";
|
|
1372
|
+
rephraseWithAIParams.questionType = config.type;
|
|
1373
|
+
await say_1.SAY.function({ cognigy, childConfigs: [], nodeId, organisationId, config: Object.assign({ say }, rephraseWithAIParams) });
|
|
1226
1374
|
if (config.type === "date" && !config.datepicker_hidePicker) {
|
|
1227
1375
|
(0, datepickerUtils_1.showDatePicker)(cognigy, config);
|
|
1228
1376
|
}
|
|
@@ -1232,9 +1380,6 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1232
1380
|
return;
|
|
1233
1381
|
}
|
|
1234
1382
|
// #endregion 2 FirstTimeNodeIsHit
|
|
1235
|
-
// if we're in a subsequent execution or we want to parse results
|
|
1236
|
-
// immediately on entry, continue with evaluation
|
|
1237
|
-
let result = (0, evaluateQuestionAnswer_1.evaluateQuestionAnswer)({ cognigy, config });
|
|
1238
1383
|
// #endregion 4 RunQuestionAnswerValidation
|
|
1239
1384
|
// #region 4.1 ResultLocationHandling
|
|
1240
1385
|
// if a result location was specified, try to get the result from that location
|
|
@@ -1253,7 +1398,6 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1253
1398
|
}
|
|
1254
1399
|
}
|
|
1255
1400
|
// #endregion 4.1 ResultLocationHandling
|
|
1256
|
-
const isValid = (0, validateQuestionAnswer_1.validateQuestionAnswer)(cognigy, config);
|
|
1257
1401
|
// hard check against null & undefined, because result can be 0 or false
|
|
1258
1402
|
if (result !== null && result !== undefined && isValid) {
|
|
1259
1403
|
// #region 5.1 AnswerIsValid
|
|
@@ -1264,7 +1408,7 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1264
1408
|
// remember a shortform of the given answer in the activeQuestion object
|
|
1265
1409
|
activeQuestion.tentativeAnswerShortform = (0, generateAnswerShortForm_1.generateAnswerShortForm)(type, result, cognigy.input.text);
|
|
1266
1410
|
// Output reconfirmationQuestion
|
|
1267
|
-
say_1.SAY.function({ cognigy, childConfigs: [], nodeId, config: { say: { type: "text", text: [reconfirmationQuestion.replace("[ANSWER]", activeQuestion.tentativeAnswerShortform)] } } });
|
|
1411
|
+
await say_1.SAY.function({ cognigy, childConfigs: [], nodeId, organisationId, config: { say: { type: "text", text: [reconfirmationQuestion.replace("[ANSWER]", activeQuestion.tentativeAnswerShortform)] } } });
|
|
1268
1412
|
// remember that we are in reconfirmation mode and stop
|
|
1269
1413
|
api.setSystemContext("reconfirmationQuestionInProgress", true);
|
|
1270
1414
|
// we need to store the input, to be able to restore it afterwards
|
|
@@ -1320,6 +1464,7 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1320
1464
|
cognigy,
|
|
1321
1465
|
childConfigs: [],
|
|
1322
1466
|
nodeId,
|
|
1467
|
+
organisationId,
|
|
1323
1468
|
config: {
|
|
1324
1469
|
flowNode: escalateIntentsGotoTarget,
|
|
1325
1470
|
absorbContext: false,
|
|
@@ -1344,6 +1489,7 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1344
1489
|
cognigy,
|
|
1345
1490
|
childConfigs: [],
|
|
1346
1491
|
nodeId,
|
|
1492
|
+
organisationId,
|
|
1347
1493
|
config: {
|
|
1348
1494
|
flowNode: escalateIntentsExecuteTarget,
|
|
1349
1495
|
absorbContext: false,
|
|
@@ -1380,10 +1526,11 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1380
1526
|
api.deleteSystemContext('activeQuestion');
|
|
1381
1527
|
return;
|
|
1382
1528
|
case "text":
|
|
1383
|
-
say_1.SAY.function({
|
|
1529
|
+
await say_1.SAY.function({
|
|
1384
1530
|
cognigy,
|
|
1385
1531
|
childConfigs: [],
|
|
1386
1532
|
nodeId,
|
|
1533
|
+
organisationId,
|
|
1387
1534
|
config: { say: escalateIntentsMessage }
|
|
1388
1535
|
});
|
|
1389
1536
|
if (escalateIntentsRepromptPrevention) {
|
|
@@ -1410,11 +1557,15 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1410
1557
|
repeatHandoverMessage: escalateIntentsRepeatHandoverMessage,
|
|
1411
1558
|
cancelIntent: escalateIntentsHandoverCancelIntent,
|
|
1412
1559
|
quickReply: escalateIntentsHandoverQuickReply,
|
|
1560
|
+
additionalCategoryIds: escalateIntentsHandoverAdditionalCategoryIds || [],
|
|
1413
1561
|
chatwootInboxId: escalateIntentsHandoverChatwootInboxId,
|
|
1414
1562
|
liveAgentInboxId: escalateIntentsHandoverLiveAgentInboxId,
|
|
1415
1563
|
sendTranscriptAsFirstMessage: escalateIntentHandoverSendTranscriptAsFirstMessage,
|
|
1416
1564
|
salesforcePrechatEntities: escalateIntentsHandoverSalesforcePrechatEntities,
|
|
1417
1565
|
salesforcePrechatDetails: escalateIntentsHandoverSalesforcePrechatDetails,
|
|
1566
|
+
eightByEightChannelId: escalateIntentsHandoverEightByEightChannelId,
|
|
1567
|
+
eightByEightQueueId: escalateIntentsHandoverEightByEightQueueId,
|
|
1568
|
+
eightByEightJSONProps: escalateIntentsHandoverEightByEightJSONProps || [],
|
|
1418
1569
|
sendResolveEvent: escalateIntentsHandoverSendResolveEvent,
|
|
1419
1570
|
resolveBehavior: escalateIntentsHandoverResolveBehavior,
|
|
1420
1571
|
agentAssistInitMessage: escalateIntentsAgentAssistInitMessage,
|
|
@@ -1458,6 +1609,7 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1458
1609
|
cognigy,
|
|
1459
1610
|
childConfigs: [],
|
|
1460
1611
|
nodeId,
|
|
1612
|
+
organisationId,
|
|
1461
1613
|
config: {
|
|
1462
1614
|
flowNode: escalateAnswersGotoTarget,
|
|
1463
1615
|
absorbContext: false,
|
|
@@ -1482,6 +1634,7 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1482
1634
|
cognigy,
|
|
1483
1635
|
childConfigs: [],
|
|
1484
1636
|
nodeId,
|
|
1637
|
+
organisationId,
|
|
1485
1638
|
config: {
|
|
1486
1639
|
flowNode: escalateAnswersExecuteTarget,
|
|
1487
1640
|
absorbContext: false,
|
|
@@ -1516,10 +1669,11 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1516
1669
|
api.deleteSystemContext('activeQuestion');
|
|
1517
1670
|
return;
|
|
1518
1671
|
case "text":
|
|
1519
|
-
say_1.SAY.function({
|
|
1672
|
+
await say_1.SAY.function({
|
|
1520
1673
|
cognigy,
|
|
1521
1674
|
childConfigs: [],
|
|
1522
1675
|
nodeId,
|
|
1676
|
+
organisationId,
|
|
1523
1677
|
config: { say: escalateAnswersMessage }
|
|
1524
1678
|
});
|
|
1525
1679
|
if (escalateAnswersRepromptPrevention) {
|
|
@@ -1548,9 +1702,13 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1548
1702
|
quickReply: escalateAnswersHandoverQuickReply,
|
|
1549
1703
|
chatwootInboxId: escalateAnswersHandoverChatwootInboxId,
|
|
1550
1704
|
liveAgentInboxId: escalateAnswersHandoverLiveAgentInboxId,
|
|
1705
|
+
additionalCategoryIds: escalateAnswersHandoverAdditionalCategoryIds || [],
|
|
1551
1706
|
sendTranscriptAsFirstMessage: escalateAnswersHandoverSendTranscriptAsFirstMessage,
|
|
1552
1707
|
salesforcePrechatEntities: escalateAnswersHandoverSalesforcePrechatEntities,
|
|
1553
1708
|
salesforcePrechatDetails: escalateAnswersHandoverSalesforcePrechatDetails,
|
|
1709
|
+
eightByEightChannelId: escalateAnswersHandoverEightByEightChannelId,
|
|
1710
|
+
eightByEightQueueId: escalateAnswersHandoverEightByEightQueueId,
|
|
1711
|
+
eightByEightJSONProps: escalateAnswersHandoverEightByEightJSONProps || [],
|
|
1554
1712
|
sendResolveEvent: escalateAnswersHandoverSendResolveEvent,
|
|
1555
1713
|
resolveBehavior: escalateAnswersHandoverResolveBehavior,
|
|
1556
1714
|
agentAssistInitMessage: escalateAnswersAgentAssistInitMessage,
|
|
@@ -1576,14 +1734,21 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1576
1734
|
if (validationMessage && !isFirstExecution && sayReprompt) {
|
|
1577
1735
|
activeQuestion.repromptCount++;
|
|
1578
1736
|
/* Output Reprompt Message */
|
|
1579
|
-
|
|
1737
|
+
rephraseWithAIParams.promtType = "reprompt";
|
|
1738
|
+
rephraseWithAIParams.questionType = config.type;
|
|
1739
|
+
rephraseWithAIParams.question = say.text[0];
|
|
1740
|
+
rephraseWithAIParams.answer = input.text;
|
|
1741
|
+
await say_1.SAY.function({ cognigy, childConfigs: [], nodeId, organisationId, config: Object.assign({ say: { type: "text", text: [validationMessage] } }, rephraseWithAIParams) });
|
|
1580
1742
|
/* If repeat toggle is on, also output question (and maybe datepicker) again */
|
|
1581
1743
|
if (validationRepeat) {
|
|
1582
|
-
|
|
1744
|
+
rephraseWithAIParams.promtType = "question";
|
|
1745
|
+
rephraseWithAIParams.questionType = config.type;
|
|
1746
|
+
await say_1.SAY.function({
|
|
1583
1747
|
cognigy,
|
|
1584
1748
|
childConfigs: [],
|
|
1585
1749
|
nodeId,
|
|
1586
|
-
|
|
1750
|
+
organisationId,
|
|
1751
|
+
config: Object.assign({ say }, rephraseWithAIParams)
|
|
1587
1752
|
});
|
|
1588
1753
|
if (config.type === "date" && !config.datepicker_hidePicker) {
|
|
1589
1754
|
(0, datepickerUtils_1.showDatePicker)(cognigy, config);
|
|
@@ -1592,11 +1757,14 @@ exports.QUESTION = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
1592
1757
|
}
|
|
1593
1758
|
else {
|
|
1594
1759
|
// output actual question
|
|
1595
|
-
|
|
1760
|
+
rephraseWithAIParams.promtType = "question";
|
|
1761
|
+
rephraseWithAIParams.questionType = config.type;
|
|
1762
|
+
await say_1.SAY.function({
|
|
1596
1763
|
cognigy,
|
|
1597
1764
|
childConfigs: [],
|
|
1598
1765
|
nodeId,
|
|
1599
|
-
|
|
1766
|
+
organisationId,
|
|
1767
|
+
config: Object.assign({ say }, rephraseWithAIParams)
|
|
1600
1768
|
});
|
|
1601
1769
|
if (config.type === "date" && !config.datepicker_hidePicker) {
|
|
1602
1770
|
(0, datepickerUtils_1.showDatePicker)(cognigy, config);
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.SAY = void 0;
|
|
4
4
|
/* Custom modules */
|
|
5
5
|
const createNodeDescriptor_1 = require("../../createNodeDescriptor");
|
|
6
|
+
const getRephraseWithAIFields_1 = require("../../helpers/generativeAI/getRephraseWithAIFields");
|
|
7
|
+
const rephraseSentenceWithAi_1 = require("../../helpers/generativeAI/rephraseSentenceWithAi");
|
|
6
8
|
exports.SAY = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
7
9
|
type: "say",
|
|
8
10
|
defaultLabel: "Say",
|
|
@@ -24,14 +26,22 @@ exports.SAY = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
24
26
|
_cognigy: {},
|
|
25
27
|
},
|
|
26
28
|
},
|
|
29
|
+
...(0, getRephraseWithAIFields_1.getRephraseWithAIFields)(),
|
|
30
|
+
].filter(field => !!field),
|
|
31
|
+
sections: [
|
|
32
|
+
(0, getRephraseWithAIFields_1.getRephraseWithAISection)(),
|
|
33
|
+
].filter(section => !!section),
|
|
34
|
+
form: [
|
|
35
|
+
{ type: "field", key: "say" },
|
|
36
|
+
{ type: "section", key: "aiEnhancedOutput" },
|
|
27
37
|
],
|
|
28
38
|
preview: {
|
|
29
39
|
key: "say",
|
|
30
40
|
type: "sayNode",
|
|
31
41
|
},
|
|
32
42
|
tags: ["basic", "message"],
|
|
33
|
-
function: async ({ cognigy, config, nodeId }) => {
|
|
34
|
-
var _a;
|
|
43
|
+
function: async ({ cognigy, config, nodeId, organisationId }) => {
|
|
44
|
+
var _a, _b, _c, _d, _e, _f;
|
|
35
45
|
const { api } = cognigy;
|
|
36
46
|
const { text, loop, linear, type, _data } = config.say;
|
|
37
47
|
/*Say nodes are always forwardable */
|
|
@@ -80,9 +90,30 @@ exports.SAY = (0, createNodeDescriptor_1.createNodeDescriptor)({
|
|
|
80
90
|
if ((_a = _data === null || _data === void 0 ? void 0 : _data._cognigy) === null || _a === void 0 ? void 0 : _a._default) {
|
|
81
91
|
delete _data._cognigy._default;
|
|
82
92
|
}
|
|
93
|
+
outputText = await (0, rephraseSentenceWithAi_1.rephraseSentenceWithAI)(outputText, config, api, organisationId);
|
|
83
94
|
api.say(outputText, _data, settings);
|
|
84
95
|
}
|
|
85
96
|
else {
|
|
97
|
+
const _cognigyDefault = (_b = _data === null || _data === void 0 ? void 0 : _data._cognigy) === null || _b === void 0 ? void 0 : _b._default;
|
|
98
|
+
const typeKey = "_" + type;
|
|
99
|
+
if (type === "quickReplies" || type === "buttons") {
|
|
100
|
+
if (((_c = _cognigyDefault === null || _cognigyDefault === void 0 ? void 0 : _cognigyDefault[typeKey]) === null || _c === void 0 ? void 0 : _c.text) && (_cognigyDefault === null || _cognigyDefault === void 0 ? void 0 : _cognigyDefault[typeKey].fallbackText)) {
|
|
101
|
+
const result = await (0, rephraseSentenceWithAi_1.rephraseMultipleSentencesWithAI)([_cognigyDefault[typeKey].text, _cognigyDefault[typeKey].fallbackText], config, api, organisationId);
|
|
102
|
+
if (result.length === 2) {
|
|
103
|
+
_cognigyDefault[typeKey].text = result[0];
|
|
104
|
+
_cognigyDefault[typeKey].fallbackText = result[1];
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else if ((_d = _cognigyDefault === null || _cognigyDefault === void 0 ? void 0 : _cognigyDefault[typeKey]) === null || _d === void 0 ? void 0 : _d.text) {
|
|
108
|
+
_cognigyDefault[typeKey].text = await (0, rephraseSentenceWithAi_1.rephraseSentenceWithAI)(_cognigyDefault[typeKey].text, config, api, organisationId);
|
|
109
|
+
}
|
|
110
|
+
else if ((_e = _cognigyDefault === null || _cognigyDefault === void 0 ? void 0 : _cognigyDefault[typeKey]) === null || _e === void 0 ? void 0 : _e.fallbackText) {
|
|
111
|
+
_cognigyDefault[typeKey].fallbackText = await (0, rephraseSentenceWithAi_1.rephraseSentenceWithAI)(_cognigyDefault[typeKey].fallbackText, config, api, organisationId);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
else if ((_f = _cognigyDefault === null || _cognigyDefault === void 0 ? void 0 : _cognigyDefault[typeKey]) === null || _f === void 0 ? void 0 : _f.fallbackText) {
|
|
115
|
+
_cognigyDefault[typeKey].fallbackText = await (0, rephraseSentenceWithAi_1.rephraseSentenceWithAI)(_cognigyDefault[typeKey].fallbackText, config, api, organisationId);
|
|
116
|
+
}
|
|
86
117
|
/**
|
|
87
118
|
* This is a say node which is set to a type other than 'text' -
|
|
88
119
|
* so we have one of the new rich-media types such as 'gallery'
|