@tiledesk/tiledesk-tybot-connector 0.2.601-rc1 → 0.3.1
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 +387 -1
- package/ExtApi.js +6 -7
- package/Logger.js +74 -0
- package/TdCache.js +81 -176
- package/TdCache_v3.js +261 -0
- package/TiledeskExpression.js +7 -3
- package/TiledeskServices/AIService.js +43 -0
- package/TiledeskServices/utils.js +99 -0
- package/index.js +305 -50
- package/logs/app.log +279 -0
- package/models/IntentsMachineFactory.js +5 -2
- package/models/MockBotsDataSource.js +19 -11
- package/models/TiledeskChatbot.js +97 -79
- package/models/TiledeskChatbotConst.js +12 -17
- package/models/TiledeskChatbotUtil.js +359 -109
- package/models/TiledeskIntentsMachine.js +1 -1
- package/models/faqKbService.js +1 -1
- package/package.json +8 -6
- package/tiledeskChatbotPlugs/DirectivesChatbotPlug.js +172 -106
- package/tiledeskChatbotPlugs/Filler.js +13 -2
- package/tiledeskChatbotPlugs/TildeskContextForCodeOrchestrator.js +8 -0
- package/tiledeskChatbotPlugs/WebhookChatbotPlug.js +13 -7
- package/tiledeskChatbotPlugs/directives/DirAddTags.js +374 -0
- package/tiledeskChatbotPlugs/directives/DirAiPrompt.js +476 -0
- package/tiledeskChatbotPlugs/directives/DirAskGPT.js +16 -19
- package/tiledeskChatbotPlugs/directives/DirAskGPTV2.js +221 -34
- package/tiledeskChatbotPlugs/directives/DirAssign.js +0 -11
- package/tiledeskChatbotPlugs/directives/DirAssignFromFunction.js +11 -21
- package/tiledeskChatbotPlugs/directives/DirAssistant.js +728 -0
- package/tiledeskChatbotPlugs/directives/DirBrevo.js +353 -0
- package/tiledeskChatbotPlugs/directives/DirCaptureUserReply.js +3 -30
- package/tiledeskChatbotPlugs/directives/DirClearTranscript.js +22 -0
- package/tiledeskChatbotPlugs/directives/DirClose.js +16 -3
- package/tiledeskChatbotPlugs/directives/DirCode.js +1 -1
- package/tiledeskChatbotPlugs/directives/DirCondition.js +0 -26
- package/tiledeskChatbotPlugs/directives/DirConnectBlock.js +182 -0
- package/tiledeskChatbotPlugs/directives/DirContactUpdate.js +121 -0
- package/tiledeskChatbotPlugs/directives/DirCustomerio.js +5 -8
- package/tiledeskChatbotPlugs/directives/DirDeflectToHelpCenter.js +11 -1
- package/tiledeskChatbotPlugs/directives/DirDepartment.js +15 -6
- package/tiledeskChatbotPlugs/directives/DirFireTiledeskEvent.js +17 -6
- package/tiledeskChatbotPlugs/directives/DirForm.js +12 -2
- package/tiledeskChatbotPlugs/directives/DirGptTask.js +83 -38
- package/tiledeskChatbotPlugs/directives/DirGptTask_OLD.js +4 -7
- package/tiledeskChatbotPlugs/directives/DirHubspot.js +5 -8
- package/tiledeskChatbotPlugs/directives/DirIfOnlineAgents.js +14 -27
- package/tiledeskChatbotPlugs/directives/DirIfOnlineAgentsV2.js +278 -0
- package/tiledeskChatbotPlugs/directives/DirIfOpenHours.js +147 -51
- package/tiledeskChatbotPlugs/directives/DirIfOpenHours_OLD.js +125 -0
- package/tiledeskChatbotPlugs/directives/DirIntent.js +8 -37
- package/tiledeskChatbotPlugs/directives/DirJSONCondition.js +5 -26
- package/tiledeskChatbotPlugs/directives/DirMessage.js +19 -17
- package/tiledeskChatbotPlugs/directives/DirMessageToBot.js +135 -0
- package/tiledeskChatbotPlugs/directives/DirMoveToAgent.js +20 -87
- package/tiledeskChatbotPlugs/directives/DirMoveToUnassigned.js +59 -0
- package/tiledeskChatbotPlugs/directives/DirQapla.js +6 -9
- package/tiledeskChatbotPlugs/directives/DirRandomReply.js +17 -7
- package/tiledeskChatbotPlugs/directives/DirRemoveCurrentBot.js +17 -7
- package/tiledeskChatbotPlugs/directives/DirReplaceBot.js +11 -2
- package/tiledeskChatbotPlugs/directives/DirReplaceBotV2.js +135 -21
- package/tiledeskChatbotPlugs/directives/DirReplaceBotV3.js +163 -0
- package/tiledeskChatbotPlugs/directives/DirReply.js +53 -9
- package/tiledeskChatbotPlugs/directives/DirReplyV2.js +347 -0
- package/tiledeskChatbotPlugs/directives/DirSendEmail.js +13 -23
- package/tiledeskChatbotPlugs/directives/DirSendWhatsapp.js +247 -0
- package/tiledeskChatbotPlugs/directives/DirSetAttributeV2.js +202 -15
- package/tiledeskChatbotPlugs/directives/DirSetConversationTags.js +13 -4
- package/tiledeskChatbotPlugs/directives/DirWait.js +21 -4
- package/tiledeskChatbotPlugs/directives/DirWebRequest.js +1 -2
- package/tiledeskChatbotPlugs/directives/DirWebRequestV2.js +166 -103
- package/tiledeskChatbotPlugs/directives/DirWhatsappByAttribute.js +2 -60
- package/tiledeskChatbotPlugs/directives/Directives.js +16 -1
- /package/tiledeskChatbotPlugs/directives/{DirOfflineHours.js → DEPRECATED_DirOfflineHours.js} +0 -0
|
@@ -0,0 +1,728 @@
|
|
|
1
|
+
let axios = require('axios');
|
|
2
|
+
let https = require("https");
|
|
3
|
+
const { Filler } = require('../Filler');
|
|
4
|
+
const { TiledeskChatbot } = require('../../models/TiledeskChatbot');
|
|
5
|
+
const { DirIntent } = require('./DirIntent');
|
|
6
|
+
|
|
7
|
+
class DirAssistant {
|
|
8
|
+
constructor(context) {
|
|
9
|
+
if (!context) {
|
|
10
|
+
throw new Error('context object is mandatory.');
|
|
11
|
+
}
|
|
12
|
+
this.context = context;
|
|
13
|
+
this.tdcache = context.tdcache;
|
|
14
|
+
this.requestId = context.requestId;
|
|
15
|
+
this.intentDir = new DirIntent(context);
|
|
16
|
+
this.API_ENDPOINT = context.API_ENDPOINT;
|
|
17
|
+
this.log = context.log;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
execute(directive, callback) {
|
|
21
|
+
let action;
|
|
22
|
+
if (directive.action) {
|
|
23
|
+
action = directive.action;
|
|
24
|
+
}
|
|
25
|
+
else {
|
|
26
|
+
console.error("Incorrect directive:", JSON.stringify(directive));
|
|
27
|
+
callback();
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
this.go(action, (stop) => {
|
|
31
|
+
if (this.log) {console.log("(DirAssistant, stop?", stop); }
|
|
32
|
+
callback(stop);
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async go(action, callback) {
|
|
37
|
+
if (this.log) {console.log("DirAssistant action:", JSON.stringify(action));}
|
|
38
|
+
let requestAttributes = null;
|
|
39
|
+
if (this.tdcache) {
|
|
40
|
+
requestAttributes =
|
|
41
|
+
await TiledeskChatbot.allParametersStatic(
|
|
42
|
+
this.tdcache, this.requestId
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const filler = new Filler();
|
|
47
|
+
const url = filler.fill(action.url, requestAttributes);
|
|
48
|
+
// prompt => Mandatory
|
|
49
|
+
// assistantId => Mandatory
|
|
50
|
+
// threadIdAttribute => Optional // default "firstThread"
|
|
51
|
+
// assignResultTo => Optional // default "assistantReply"
|
|
52
|
+
// assignErrorTo => Optional // default "assistantError"
|
|
53
|
+
// action.settings.timeout => Optional
|
|
54
|
+
|
|
55
|
+
let assignResultTo = "assistantReply";
|
|
56
|
+
if (action.assignResultTo) {
|
|
57
|
+
assignResultTo = action.assignResultTo;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
let assignErrorTo = "assistantError";
|
|
61
|
+
if (action.assignErrorTo) {
|
|
62
|
+
assignErrorTo = action.assignErrorTo;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
let threadIdAttribute = "firstThread";
|
|
66
|
+
if (action.threadIdAttribute) {
|
|
67
|
+
threadIdAttribute = action.threadIdAttribute;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let _assistantId = null;
|
|
71
|
+
if (action.assistantId) { // mandatory
|
|
72
|
+
_assistantId = action.assistantId;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
// TODO: LOG SETTINGS ERROR
|
|
76
|
+
console.error("DirAssistant error: no assistantId.");
|
|
77
|
+
callback();
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
let _prompt = null;
|
|
82
|
+
if (action.prompt) { // mandatory
|
|
83
|
+
_prompt = action.prompt;
|
|
84
|
+
}
|
|
85
|
+
else {
|
|
86
|
+
// TODO: LOG SETTINGS ERROR
|
|
87
|
+
console.error("DirAssistant error: no prompt.");
|
|
88
|
+
callback();
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
let assistantId = _assistantId;
|
|
93
|
+
try {
|
|
94
|
+
assistantId = filler.fill(_assistantId, requestAttributes);
|
|
95
|
+
}
|
|
96
|
+
catch(error) {
|
|
97
|
+
console.error("Error while filling assistantId:", error);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let prompt = _prompt;
|
|
101
|
+
try {
|
|
102
|
+
prompt = filler.fill(_prompt, requestAttributes);
|
|
103
|
+
}
|
|
104
|
+
catch(error) {
|
|
105
|
+
console.error("Error while filling prompt:", error);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (this.log) {
|
|
109
|
+
console.log("settings ok");
|
|
110
|
+
console.log("prompt:", prompt);
|
|
111
|
+
console.log("assistantId:", assistantId);
|
|
112
|
+
}
|
|
113
|
+
// Condition branches
|
|
114
|
+
let trueIntent = action.trueIntent;
|
|
115
|
+
let falseIntent = action.falseIntent;
|
|
116
|
+
if (trueIntent && trueIntent.trim() === "") {
|
|
117
|
+
trueIntent = null;
|
|
118
|
+
}
|
|
119
|
+
if (falseIntent && falseIntent.trim() === "") {
|
|
120
|
+
falseIntent = null;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
this.timeout = this.#webrequest_timeout(action, 20000, 1, 300000);
|
|
124
|
+
|
|
125
|
+
let apikey = await this.getGPT_APIKEY();
|
|
126
|
+
if (this.log) {console.log("apikey:", apikey);}
|
|
127
|
+
if (!apikey) {
|
|
128
|
+
const reply = "OpenAI APIKEY is mandatory for ChatGPT Assistants. Add your personal OpenAI APIKEY in Settings > Integrations";
|
|
129
|
+
if (this.log) { console.error(reply); };
|
|
130
|
+
await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, assignErrorTo, reply);
|
|
131
|
+
if (falseIntent) {
|
|
132
|
+
await this.#executeCondition(false, trueIntent, null, falseIntent, null);
|
|
133
|
+
callback(true);
|
|
134
|
+
}
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
apikey = "Bearer " + apikey;
|
|
139
|
+
}
|
|
140
|
+
let threadId = null;
|
|
141
|
+
try {
|
|
142
|
+
threadId = requestAttributes[threadIdAttribute];
|
|
143
|
+
if (!threadId || (threadId && threadId.trim() === '') ) {
|
|
144
|
+
// create thread if it doesn't exist
|
|
145
|
+
if (this.log) {console.log("Creating thread");}
|
|
146
|
+
const thread = await this.createThread(apikey);
|
|
147
|
+
if (this.log) {console.log("Thread crated.");}
|
|
148
|
+
threadId = thread.id;
|
|
149
|
+
await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, threadIdAttribute, threadId);
|
|
150
|
+
if (this.log) {
|
|
151
|
+
console.log("thread:", thread);
|
|
152
|
+
console.log("threadId:", threadId);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
if (this.log) { console.log("Reusing threadId (used flow attribute:" + threadIdAttribute + "):", threadId); }
|
|
157
|
+
}
|
|
158
|
+
await this.addMessage(prompt, threadId, apikey);
|
|
159
|
+
if (this.log) {console.log("Message added.");}
|
|
160
|
+
await this.runThreadOnAssistant(assistantId, threadId, apikey);
|
|
161
|
+
let messages = await this.threadMessages(threadId, apikey);
|
|
162
|
+
let lastMessage = null;
|
|
163
|
+
if (messages && messages.data && messages.data.length > 0 && messages.data[0]) {
|
|
164
|
+
if (messages.data[0].content.length > 0 && messages.data[0].content[0] && messages.data[0].content[0].text) {
|
|
165
|
+
lastMessage = messages.data[0].content[0].text.value;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
// process.exit(0);
|
|
170
|
+
if (lastMessage !== null) {
|
|
171
|
+
await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, assignResultTo, lastMessage);
|
|
172
|
+
await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, "lastMessageData", messages.data[0].content); // content is an array, see on this source end for messages structure example, including content. Ex get annotation[0]: content[0].text.annotations[0]
|
|
173
|
+
if (trueIntent) {
|
|
174
|
+
await this.#executeCondition(true, trueIntent, null, falseIntent, null);
|
|
175
|
+
callback(true);
|
|
176
|
+
}
|
|
177
|
+
else {
|
|
178
|
+
callback(false);
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, assignResultTo, null);
|
|
184
|
+
if (falseIntent) {
|
|
185
|
+
await this.#executeCondition(false, trueIntent, null, falseIntent, null);
|
|
186
|
+
callback(true);
|
|
187
|
+
}
|
|
188
|
+
else {
|
|
189
|
+
callback(false);
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
catch (error) {
|
|
195
|
+
if (this.log) { console.error("error:", error); }
|
|
196
|
+
await TiledeskChatbot.addParameterStatic(this.context.tdcache, this.context.requestId, assignErrorTo, error);
|
|
197
|
+
if (falseIntent) {
|
|
198
|
+
await this.#executeCondition(false, trueIntent, null, falseIntent, null);
|
|
199
|
+
}
|
|
200
|
+
callback(true);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
async #executeCondition(result, trueIntent, trueIntentAttributes, falseIntent, falseIntentAttributes, callback) {
|
|
207
|
+
let trueIntentDirective = null;
|
|
208
|
+
if (trueIntent) {
|
|
209
|
+
trueIntentDirective = DirIntent.intentDirectiveFor(trueIntent, trueIntentAttributes);
|
|
210
|
+
}
|
|
211
|
+
let falseIntentDirective = null;
|
|
212
|
+
if (falseIntent) {
|
|
213
|
+
falseIntentDirective = DirIntent.intentDirectiveFor(falseIntent, falseIntentAttributes);
|
|
214
|
+
}
|
|
215
|
+
if (result === true) {
|
|
216
|
+
if (trueIntentDirective) {
|
|
217
|
+
this.intentDir.execute(trueIntentDirective, () => {
|
|
218
|
+
if (callback) {
|
|
219
|
+
callback();
|
|
220
|
+
}
|
|
221
|
+
});
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
if (this.log) {console.log("No trueIntentDirective specified");}
|
|
225
|
+
if (callback) {
|
|
226
|
+
callback();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
if (falseIntentDirective) {
|
|
232
|
+
this.intentDir.execute(falseIntentDirective, () => {
|
|
233
|
+
if (callback) {
|
|
234
|
+
callback();
|
|
235
|
+
}
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
if (this.log) {console.log("No falseIntentDirective specified");}
|
|
240
|
+
if (callback) {
|
|
241
|
+
callback();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
#webrequest_timeout(action, default_timeout, min, max) {
|
|
248
|
+
let timeout = default_timeout;
|
|
249
|
+
if (!action.settings) {
|
|
250
|
+
return timeout;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (action.settings.timeout) {
|
|
254
|
+
if ((typeof action.settings.timeout === "number") && action.settings.timeout > min && action.settings.timeout < max) {
|
|
255
|
+
timeout = Math.round(action.settings.timeout)
|
|
256
|
+
// console.log("new timeout:", timeout);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
return timeout
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
async getGPT_APIKEY() {
|
|
263
|
+
if (process.env.TEST_OPENAI_APIKEY) {
|
|
264
|
+
return process.env.TEST_OPENAI_APIKEY
|
|
265
|
+
}
|
|
266
|
+
else {
|
|
267
|
+
return await this.getKeyFromIntegrations();
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
async createThread(apikey) {
|
|
272
|
+
if (this.log) { console.log("creating thread..."); }
|
|
273
|
+
return new Promise( async (resolve, reject) => {
|
|
274
|
+
const url = "https://api.openai.com/v1/threads";
|
|
275
|
+
const headers = {
|
|
276
|
+
"Authorization": apikey,
|
|
277
|
+
"OpenAI-Beta": "assistants=v2"
|
|
278
|
+
}
|
|
279
|
+
const HTTPREQUEST = {
|
|
280
|
+
url: url,
|
|
281
|
+
headers: headers,
|
|
282
|
+
json: '', // no old messages on creation
|
|
283
|
+
method: "POST",
|
|
284
|
+
timeout: this.timeout
|
|
285
|
+
};
|
|
286
|
+
if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
|
|
287
|
+
this.#myrequest(
|
|
288
|
+
HTTPREQUEST, async (err, res) => {
|
|
289
|
+
let status = res.status;
|
|
290
|
+
if (err) {
|
|
291
|
+
if (this.log) {console.error("DirAssistant error:", err);}
|
|
292
|
+
reject(err);
|
|
293
|
+
}
|
|
294
|
+
else if(res.status >= 200 && res.status <= 299) {
|
|
295
|
+
if (this.log) {console.log("got threadid res:", res);}
|
|
296
|
+
let thread = res.data;
|
|
297
|
+
resolve(thread)
|
|
298
|
+
}
|
|
299
|
+
else {
|
|
300
|
+
reject(new Error("Thread creation status != 200:", status));
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
);
|
|
304
|
+
});
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async addMessage(prompt, threadId, apikey) {
|
|
308
|
+
|
|
309
|
+
// POST https://api.openai.com/v1/threads/{{threadID}}/messages
|
|
310
|
+
|
|
311
|
+
// JSON
|
|
312
|
+
/*
|
|
313
|
+
{
|
|
314
|
+
"role": "user",
|
|
315
|
+
"content": {{last_user_text | json}},
|
|
316
|
+
"attachments": [
|
|
317
|
+
{
|
|
318
|
+
"file_id": "file-9rf2OwoLy22Q6bePkO0Zmhlc",
|
|
319
|
+
"tools": [
|
|
320
|
+
{
|
|
321
|
+
"type": "code_interpreter"
|
|
322
|
+
}
|
|
323
|
+
]
|
|
324
|
+
}
|
|
325
|
+
]
|
|
326
|
+
}
|
|
327
|
+
*/
|
|
328
|
+
const json_payload = {
|
|
329
|
+
"role": "user",
|
|
330
|
+
"content": prompt
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
return new Promise( async (resolve, reject) => {
|
|
334
|
+
const url = `https://api.openai.com/v1/threads/${threadId}/messages`;
|
|
335
|
+
const headers = {
|
|
336
|
+
"Authorization": apikey,
|
|
337
|
+
"OpenAI-Beta": "assistants=v2"
|
|
338
|
+
}
|
|
339
|
+
const HTTPREQUEST = {
|
|
340
|
+
url: url,
|
|
341
|
+
headers: headers,
|
|
342
|
+
json: json_payload,
|
|
343
|
+
method: "POST",
|
|
344
|
+
timeout: this.timeout
|
|
345
|
+
};
|
|
346
|
+
if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
|
|
347
|
+
this.#myrequest(
|
|
348
|
+
HTTPREQUEST, async (err, res) => {
|
|
349
|
+
let status = res.status;
|
|
350
|
+
if (err) {
|
|
351
|
+
if (this.log) {console.error("DirAssistant error:", err);}
|
|
352
|
+
reject(err);
|
|
353
|
+
}
|
|
354
|
+
else if(res.status >= 200 && res.status <= 299) {
|
|
355
|
+
if (this.log) {console.log("got response data:", res.data);}
|
|
356
|
+
// let return_body = res.data;
|
|
357
|
+
resolve();
|
|
358
|
+
}
|
|
359
|
+
else {
|
|
360
|
+
reject(new Error("Message add status != 200:", status));
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
);
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
async runThreadOnAssistant(assistantId, threadId, apikey) {
|
|
368
|
+
let _run = await this.createRun(threadId, assistantId, apikey);
|
|
369
|
+
if (this.log) {console.log("Got run:", _run);}
|
|
370
|
+
let runId = _run.id;
|
|
371
|
+
if (this.log) {console.log("runId:", runId);}
|
|
372
|
+
let status = null;
|
|
373
|
+
do {
|
|
374
|
+
if (this.log) {console.log("Getting run...");}
|
|
375
|
+
const wait_for = 2000;
|
|
376
|
+
if (this.log) {console.log("Waiting:", wait_for);}
|
|
377
|
+
await new Promise(resolve => setTimeout(resolve, wait_for));
|
|
378
|
+
let run = await this.getRun(threadId, runId, apikey);
|
|
379
|
+
status = run.status;
|
|
380
|
+
if (this.log) {console.log("Run status:", status);}
|
|
381
|
+
}
|
|
382
|
+
while (status === "queued" || status === "in_progress" || status === "requires_action" && status === "cancelling");
|
|
383
|
+
// while (status != "completed" && status != "cancelled" && status != "failed" && status != "expired");
|
|
384
|
+
// queued, in_progress, requires_action, cancelling
|
|
385
|
+
if (this.log) {console.log("Run end.");}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
async createRun(threadId, assistantId, apikey) {
|
|
389
|
+
const json_payload = {
|
|
390
|
+
"assistant_id": assistantId
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
return new Promise( async (resolve, reject) => {
|
|
394
|
+
if (this.log) {console.log("adding message to thread...");}
|
|
395
|
+
const url = `https://api.openai.com/v1/threads/${threadId}/runs`;
|
|
396
|
+
const headers = {
|
|
397
|
+
"Authorization": apikey,
|
|
398
|
+
"OpenAI-Beta": "assistants=v2"
|
|
399
|
+
}
|
|
400
|
+
const HTTPREQUEST = {
|
|
401
|
+
url: url,
|
|
402
|
+
headers: headers,
|
|
403
|
+
json: json_payload,
|
|
404
|
+
method: "POST",
|
|
405
|
+
timeout: this.timeout
|
|
406
|
+
};
|
|
407
|
+
if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
|
|
408
|
+
this.#myrequest(
|
|
409
|
+
HTTPREQUEST, async (err, res) => {
|
|
410
|
+
let status = res.status;
|
|
411
|
+
if (err) {
|
|
412
|
+
if (this.log) {console.error("DirAssistant error:", err);}
|
|
413
|
+
reject(err);
|
|
414
|
+
}
|
|
415
|
+
else if(res.status >= 200 && res.status <= 299) {
|
|
416
|
+
if (this.log) {console.log("got response data:", res.data);}
|
|
417
|
+
// let return_body = res.data;
|
|
418
|
+
resolve(res.data);
|
|
419
|
+
}
|
|
420
|
+
else {
|
|
421
|
+
reject(new Error("Message add status != 200:", status));
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
);
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
async getRun(threadId, runId, apikey) {
|
|
429
|
+
return new Promise( async (resolve, reject) => {
|
|
430
|
+
const url = `https://api.openai.com/v1/threads/${threadId}/runs/${runId}`;
|
|
431
|
+
const headers = {
|
|
432
|
+
"Authorization": apikey,
|
|
433
|
+
"OpenAI-Beta": "assistants=v2"
|
|
434
|
+
}
|
|
435
|
+
const HTTPREQUEST = {
|
|
436
|
+
url: url,
|
|
437
|
+
headers: headers,
|
|
438
|
+
json: null,
|
|
439
|
+
method: "GET",
|
|
440
|
+
timeout: this.timeout
|
|
441
|
+
};
|
|
442
|
+
if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
|
|
443
|
+
this.#myrequest(
|
|
444
|
+
HTTPREQUEST, async (err, res) => {
|
|
445
|
+
let status = res.status;
|
|
446
|
+
if (err) {
|
|
447
|
+
if (this.log) {console.error("DirAssistant error:", err);}
|
|
448
|
+
reject(err);
|
|
449
|
+
}
|
|
450
|
+
else if(res.status >= 200 && res.status <= 299) {
|
|
451
|
+
if (this.log) {console.log("got response data:", res.data);}
|
|
452
|
+
// let return_body = res.data;
|
|
453
|
+
resolve(res.data);
|
|
454
|
+
}
|
|
455
|
+
else {
|
|
456
|
+
reject(new Error("Message add status != 200:", status));
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
);
|
|
460
|
+
});
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
async threadMessages(threadId, apikey) {
|
|
464
|
+
return new Promise( async (resolve, reject) => {
|
|
465
|
+
const url = `https://api.openai.com/v1/threads/${threadId}/messages`;
|
|
466
|
+
const headers = {
|
|
467
|
+
"Authorization": apikey,
|
|
468
|
+
"OpenAI-Beta": "assistants=v2"
|
|
469
|
+
}
|
|
470
|
+
const HTTPREQUEST = {
|
|
471
|
+
url: url,
|
|
472
|
+
headers: headers,
|
|
473
|
+
json: null,
|
|
474
|
+
method: "GET",
|
|
475
|
+
timeout: this.timeout
|
|
476
|
+
};
|
|
477
|
+
if (this.log) {console.log("DirAssistant HTTPREQUEST", HTTPREQUEST);}
|
|
478
|
+
this.#myrequest(
|
|
479
|
+
HTTPREQUEST, async (err, res) => {
|
|
480
|
+
let status = res.status;
|
|
481
|
+
if (err) {
|
|
482
|
+
if (this.log) {console.error("DirAssistant error:", err);}
|
|
483
|
+
reject(err);
|
|
484
|
+
}
|
|
485
|
+
else if(res.status >= 200 && res.status <= 299) {
|
|
486
|
+
if (this.log) {console.log("got response data:", res.data);}
|
|
487
|
+
// let return_body = res.data;
|
|
488
|
+
resolve(res.data);
|
|
489
|
+
}
|
|
490
|
+
else {
|
|
491
|
+
reject(new Error("Message add status != 200:", status));
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
);
|
|
495
|
+
});
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
async getKeyFromIntegrations() {
|
|
499
|
+
return new Promise((resolve) => {
|
|
500
|
+
|
|
501
|
+
const INTEGRATIONS_HTTPREQUEST = {
|
|
502
|
+
url: this.API_ENDPOINT + "/" + this.context.projectId + "/integration/name/openai",
|
|
503
|
+
headers: {
|
|
504
|
+
'Content-Type': 'application/json',
|
|
505
|
+
'Authorization': 'JWT ' + this.context.token
|
|
506
|
+
},
|
|
507
|
+
method: "GET"
|
|
508
|
+
}
|
|
509
|
+
if (this.log) { console.log("DirAssistant INTEGRATIONS_HTTPREQUEST ", INTEGRATIONS_HTTPREQUEST) }
|
|
510
|
+
|
|
511
|
+
this.#myrequest(
|
|
512
|
+
INTEGRATIONS_HTTPREQUEST, async (err, res) => {
|
|
513
|
+
if (err) {
|
|
514
|
+
resolve(null);
|
|
515
|
+
} else {
|
|
516
|
+
let integration = res.data;
|
|
517
|
+
if (integration &&
|
|
518
|
+
integration.value) {
|
|
519
|
+
resolve(integration.value.apikey)
|
|
520
|
+
}
|
|
521
|
+
else {
|
|
522
|
+
resolve(null)
|
|
523
|
+
}
|
|
524
|
+
}
|
|
525
|
+
})
|
|
526
|
+
})
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
#myrequest(options, callback) {
|
|
530
|
+
try {
|
|
531
|
+
if (this.log) {
|
|
532
|
+
console.log("API URL:", options.url);
|
|
533
|
+
//console.log("** Options:", JSON.stringify(options));
|
|
534
|
+
// Stringify "options". FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - START
|
|
535
|
+
let cache = [];
|
|
536
|
+
let str_Options = JSON.stringify(options, function(key, value) { // try to use a separate function
|
|
537
|
+
if (typeof value === 'object' && value != null) {
|
|
538
|
+
if (cache.indexOf(value) !== -1) {
|
|
539
|
+
return;
|
|
540
|
+
}
|
|
541
|
+
cache.push(value);
|
|
542
|
+
}
|
|
543
|
+
return value;
|
|
544
|
+
});
|
|
545
|
+
console.log("** Options:", str_Options);
|
|
546
|
+
|
|
547
|
+
|
|
548
|
+
}
|
|
549
|
+
let axios_options = {
|
|
550
|
+
url: options.url,
|
|
551
|
+
method: options.method,
|
|
552
|
+
params: options.params,
|
|
553
|
+
headers: options.headers,
|
|
554
|
+
timeout: options.timeout
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
if (options.json !== null) {
|
|
558
|
+
axios_options.data = options.json
|
|
559
|
+
}
|
|
560
|
+
// if (this.log) {
|
|
561
|
+
// console.log("axios_options:", JSON.stringify(axios_options));
|
|
562
|
+
// }
|
|
563
|
+
if (options.url.startsWith("https:")) {
|
|
564
|
+
const httpsAgent = new https.Agent({
|
|
565
|
+
rejectUnauthorized: false,
|
|
566
|
+
});
|
|
567
|
+
axios_options.httpsAgent = httpsAgent;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
axios(axios_options)
|
|
571
|
+
.then((res) => {
|
|
572
|
+
if (this.log) {
|
|
573
|
+
// console.log("Success Response:", res);
|
|
574
|
+
console.log("Response for url:", options.url);
|
|
575
|
+
console.log("Response headers:\n", JSON.stringify(res.headers));
|
|
576
|
+
}
|
|
577
|
+
if (callback) {
|
|
578
|
+
callback(null, res);
|
|
579
|
+
}
|
|
580
|
+
})
|
|
581
|
+
.catch( (err) => {
|
|
582
|
+
if (this.log) {
|
|
583
|
+
if (err.response) {
|
|
584
|
+
console.log("Error Response data:", err.response.data);
|
|
585
|
+
}
|
|
586
|
+
// FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - START
|
|
587
|
+
let cache = [];
|
|
588
|
+
let error_log = JSON.stringify(err, function(key, value) { // try to use a separate function
|
|
589
|
+
if (typeof value === 'object' && value != null) {
|
|
590
|
+
if (cache.indexOf(value) !== -1) {
|
|
591
|
+
return;
|
|
592
|
+
}
|
|
593
|
+
cache.push(value);
|
|
594
|
+
}
|
|
595
|
+
return value;
|
|
596
|
+
});
|
|
597
|
+
console.error("(DirAssistant) An error occurred: ", error_log);
|
|
598
|
+
// FIX THE STRINGIFY OF CIRCULAR STRUCTURE BUG - END
|
|
599
|
+
// console.error("An error occurred:", JSON.stringify(err));
|
|
600
|
+
}
|
|
601
|
+
if (callback) {
|
|
602
|
+
let status = 1000;
|
|
603
|
+
let cache = [];
|
|
604
|
+
let str_error = JSON.stringify(err, function(key, value) { // try to use a separate function
|
|
605
|
+
if (typeof value === 'object' && value != null) {
|
|
606
|
+
if (cache.indexOf(value) !== -1) {
|
|
607
|
+
return;
|
|
608
|
+
}
|
|
609
|
+
cache.push(value);
|
|
610
|
+
}
|
|
611
|
+
return value;
|
|
612
|
+
});
|
|
613
|
+
let error = JSON.parse(str_error) // "status" disappears without this trick
|
|
614
|
+
let errorMessage = JSON.stringify(error);
|
|
615
|
+
if (error.status) {
|
|
616
|
+
status = error.status;
|
|
617
|
+
}
|
|
618
|
+
if (error.message) {
|
|
619
|
+
errorMessage = error.message;
|
|
620
|
+
}
|
|
621
|
+
let data = null;
|
|
622
|
+
if (err.response) {
|
|
623
|
+
data = err.response.data;
|
|
624
|
+
}
|
|
625
|
+
callback(
|
|
626
|
+
{
|
|
627
|
+
status: status,
|
|
628
|
+
data: data,
|
|
629
|
+
error: errorMessage
|
|
630
|
+
}, data
|
|
631
|
+
);
|
|
632
|
+
}
|
|
633
|
+
});
|
|
634
|
+
}
|
|
635
|
+
catch(error) {
|
|
636
|
+
console.error("Error:", error);
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
|
|
643
|
+
|
|
644
|
+
module.exports = { DirAssistant };
|
|
645
|
+
|
|
646
|
+
// Messages list response example
|
|
647
|
+
|
|
648
|
+
/*
|
|
649
|
+
{
|
|
650
|
+
"object": "list",
|
|
651
|
+
"data": [
|
|
652
|
+
{
|
|
653
|
+
"id": "msg_FfKaNU82uBYQU9gANFkKJ5Wi",
|
|
654
|
+
"object": "thread.message",
|
|
655
|
+
"created_at": 1721681044,
|
|
656
|
+
"assistant_id": null,
|
|
657
|
+
"thread_id": "thread_fN0rAdyJlPmN9uteMP0yWsCl",
|
|
658
|
+
"run_id": null,
|
|
659
|
+
"role": "user",
|
|
660
|
+
"content": [
|
|
661
|
+
{
|
|
662
|
+
"type": "text",
|
|
663
|
+
"text": {
|
|
664
|
+
"value": "vendete sedie di altezza superiore o uguale a 50 cm?",
|
|
665
|
+
"annotations": []
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
],
|
|
669
|
+
"file_ids": [],
|
|
670
|
+
"metadata": {}
|
|
671
|
+
},
|
|
672
|
+
{
|
|
673
|
+
"id": "msg_Ddxnqi7M9vvLdS9YYO4FHjVt",
|
|
674
|
+
"object": "thread.message",
|
|
675
|
+
"created_at": 1721680934,
|
|
676
|
+
"assistant_id": "asst_qNjiwCVxo3kL2mnN1QyP50Zb",
|
|
677
|
+
"thread_id": "thread_fN0rAdyJlPmN9uteMP0yWsCl",
|
|
678
|
+
"run_id": "run_k8mPIrZPnsO0hAiezD9y2f1t",
|
|
679
|
+
"role": "assistant",
|
|
680
|
+
"content": [
|
|
681
|
+
{
|
|
682
|
+
"type": "text",
|
|
683
|
+
"text": {
|
|
684
|
+
"value": "Una delle best practices raccomandate per garantire un alto livello di sicurezza informatica per la linea di prodotti \"boss\" è la seguente:\n\n- Aggiornare i dispositivi con l'ultima versione del firmware disponibile. È possibile consultare il portale KSA per verificare la disponibilità degli aggiornamenti【6:0†source】.\n\nSe hai altri dubbi o necessiti di ulteriori informazioni, non esitare a chiedere!",
|
|
685
|
+
"annotations": [
|
|
686
|
+
{
|
|
687
|
+
"type": "file_citation",
|
|
688
|
+
"text": "【6:0†source】",
|
|
689
|
+
"start_index": 305,
|
|
690
|
+
"end_index": 317,
|
|
691
|
+
"file_citation": {
|
|
692
|
+
"file_id": "file-dwR6qSwVUIrhImd9espzExGw",
|
|
693
|
+
"quote": ""
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
]
|
|
697
|
+
}
|
|
698
|
+
}
|
|
699
|
+
],
|
|
700
|
+
"file_ids": [],
|
|
701
|
+
"metadata": {}
|
|
702
|
+
},
|
|
703
|
+
{
|
|
704
|
+
"id": "msg_ng244T4mymroFWZ912r9DvWZ",
|
|
705
|
+
"object": "thread.message",
|
|
706
|
+
"created_at": 1721680931,
|
|
707
|
+
"assistant_id": null,
|
|
708
|
+
"thread_id": "thread_fN0rAdyJlPmN9uteMP0yWsCl",
|
|
709
|
+
"run_id": null,
|
|
710
|
+
"role": "user",
|
|
711
|
+
"content": [
|
|
712
|
+
{
|
|
713
|
+
"type": "text",
|
|
714
|
+
"text": {
|
|
715
|
+
"value": "dimmi una delle best practices che conosci",
|
|
716
|
+
"annotations": []
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
],
|
|
720
|
+
"file_ids": [],
|
|
721
|
+
"metadata": {}
|
|
722
|
+
}
|
|
723
|
+
],
|
|
724
|
+
"first_id": "msg_FfKaNU82uBYQU9gANFkKJ5Wi",
|
|
725
|
+
"last_id": "msg_ng244T4mymroFWZ912r9DvWZ",
|
|
726
|
+
"has_more": false
|
|
727
|
+
}
|
|
728
|
+
*/
|