@tiledesk/tiledesk-server 2.19.4 → 2.19.6
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 +7 -0
- package/models/kb_setting.js +2 -99
- package/package.json +1 -1
- package/routes/answered.js +243 -264
- package/routes/kb.js +162 -126
- package/routes/unanswered.js +277 -296
- package/routes/webhook.js +1 -2
- package/services/aiManager.js +41 -23
- package/services/kbQuestionService.js +98 -0
- package/test/kbRoute.js +148 -7
package/services/aiManager.js
CHANGED
|
@@ -21,6 +21,7 @@ const default_engine_hybrid = require('../config/kb/engine.hybrid');
|
|
|
21
21
|
const default_embedding = require('../config/kb/embedding');
|
|
22
22
|
const integrationService = require('./integrationService');
|
|
23
23
|
const situatedContext = require('../config/kb/situatedContext');
|
|
24
|
+
const { MODELS_MULTIPLIER } = require('../utils/aiUtils');
|
|
24
25
|
|
|
25
26
|
// Job managers
|
|
26
27
|
let jobManager = new JobManager(AMQP_MANAGER_URL, {
|
|
@@ -94,8 +95,7 @@ class AiManager {
|
|
|
94
95
|
this.saveBulk(operations, kbs, namespace.id_project, namespace.id).then( async (result) => {
|
|
95
96
|
let hybrid = namespace.hybrid;
|
|
96
97
|
let engine = namespace.engine || default_engine;
|
|
97
|
-
let embedding = namespace.embedding
|
|
98
|
-
embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
|
|
98
|
+
let embedding = this.normalizeEmbedding(namespace.embedding);
|
|
99
99
|
|
|
100
100
|
let situated_context;
|
|
101
101
|
if (options.situated_context) {
|
|
@@ -145,7 +145,7 @@ class AiManager {
|
|
|
145
145
|
namespace: namespace.id,
|
|
146
146
|
refresh_rate: options.refresh_rate,
|
|
147
147
|
engine: namespace.engine,
|
|
148
|
-
embedding: namespace.embedding,
|
|
148
|
+
embedding: this.normalizeEmbedding(namespace.embedding),
|
|
149
149
|
hybrid: namespace.hybrid,
|
|
150
150
|
...(options.situated_context && { situated_context: options.situated_context }),
|
|
151
151
|
}
|
|
@@ -448,7 +448,7 @@ class AiManager {
|
|
|
448
448
|
if (err) {
|
|
449
449
|
winston.error("deleteSitemap: deleteSchedule error for kb " + kb._id, err);
|
|
450
450
|
}
|
|
451
|
-
|
|
451
|
+
winston.info("deleteSitemap: deleteSchedule result for kb " + kb._id, result);
|
|
452
452
|
resolve(result);
|
|
453
453
|
});
|
|
454
454
|
});
|
|
@@ -514,25 +514,6 @@ class AiManager {
|
|
|
514
514
|
return true;
|
|
515
515
|
}
|
|
516
516
|
|
|
517
|
-
// from webhook
|
|
518
|
-
// async scheduleScrape(resources) {
|
|
519
|
-
|
|
520
|
-
// let scheduler = new Scheduler({ jobManager: jobManager });
|
|
521
|
-
|
|
522
|
-
// resources.forEach(r => {
|
|
523
|
-
// winston.debug("(Webhook) Schedule job with following data: ", r);
|
|
524
|
-
// scheduler.trainSchedule(r, async (err, result) => {
|
|
525
|
-
// if (err) {
|
|
526
|
-
// winston.error("Scheduling error: ", err);
|
|
527
|
-
// } else {
|
|
528
|
-
// winston.info("Scheduling result: ", result);
|
|
529
|
-
// }
|
|
530
|
-
// });
|
|
531
|
-
// })
|
|
532
|
-
|
|
533
|
-
// return true;
|
|
534
|
-
// }
|
|
535
|
-
|
|
536
517
|
async startScrape(data) {
|
|
537
518
|
|
|
538
519
|
if (!data.gptkey) {
|
|
@@ -615,6 +596,16 @@ class AiManager {
|
|
|
615
596
|
})
|
|
616
597
|
}
|
|
617
598
|
|
|
599
|
+
normalizeEmbedding(embedding) {
|
|
600
|
+
const normalizedEmbedding = (embedding && typeof embedding.toObject === 'function')
|
|
601
|
+
? embedding.toObject()
|
|
602
|
+
: (embedding || default_embedding);
|
|
603
|
+
return {
|
|
604
|
+
...normalizedEmbedding,
|
|
605
|
+
api_key: process.env.EMBEDDING_API_KEY || process.env.GPTKEY
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
|
|
618
609
|
normalizeSituatedContext(enable = false) {
|
|
619
610
|
situatedContext.enable = enable;
|
|
620
611
|
return situatedContext.enable
|
|
@@ -625,6 +616,33 @@ class AiManager {
|
|
|
625
616
|
: undefined;
|
|
626
617
|
}
|
|
627
618
|
|
|
619
|
+
async getTrackingTokens({ qaResult, publicKey, model, obj, quoteManager, project }) {
|
|
620
|
+
if (publicKey !== true) {
|
|
621
|
+
return qaResult.prompt_token_size;
|
|
622
|
+
}
|
|
623
|
+
let modelKey;
|
|
624
|
+
if (typeof model === 'string') {
|
|
625
|
+
modelKey = model;
|
|
626
|
+
} else if (model && typeof model.name === 'string') {
|
|
627
|
+
modelKey = model.name;
|
|
628
|
+
}
|
|
629
|
+
let multiplier = MODELS_MULTIPLIER[modelKey];
|
|
630
|
+
if (!multiplier) {
|
|
631
|
+
multiplier = 1;
|
|
632
|
+
winston.info("No multiplier found for AI model (qa) " + modelKey);
|
|
633
|
+
}
|
|
634
|
+
obj.multiplier = multiplier;
|
|
635
|
+
obj.tokens = qaResult.prompt_token_size;
|
|
636
|
+
const incremented_key = await quoteManager.incrementTokenCount(project, obj);
|
|
637
|
+
winston.verbose("incremented_key: ", incremented_key);
|
|
638
|
+
const trackingTokens = obj.tokens * obj.multiplier;
|
|
639
|
+
if (qaResult != null && typeof qaResult.prompt_token_size === 'number') {
|
|
640
|
+
qaResult.legacy_prompt_token_size = qaResult.prompt_token_size;
|
|
641
|
+
qaResult.prompt_token_size = trackingTokens;
|
|
642
|
+
}
|
|
643
|
+
return trackingTokens;
|
|
644
|
+
}
|
|
645
|
+
|
|
628
646
|
}
|
|
629
647
|
|
|
630
648
|
const aiManager = new AiManager();
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
const { Namespace, AnsweredQuestion, UnansweredQuestion } = require('../models/kb_setting');
|
|
2
|
+
const winston = require('../config/winston');
|
|
3
|
+
|
|
4
|
+
class KbQuestionService {
|
|
5
|
+
|
|
6
|
+
constructor() {}
|
|
7
|
+
|
|
8
|
+
async createAnsweredQuestion(id_project, data) {
|
|
9
|
+
try {
|
|
10
|
+
const { namespace, question, answer, tokens, request_id } = data;
|
|
11
|
+
|
|
12
|
+
if (!namespace || !question || !answer) {
|
|
13
|
+
throw new Error({ status: 422, error: 'Missing required parameters: namespace, question and answer' });
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const isValidNamespace = await this.validateNamespace(id_project, namespace);
|
|
17
|
+
if (!isValidNamespace) {
|
|
18
|
+
throw new Error({ status: 403, error: 'Not allowed. The namespace does not belong to the current project.' });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const answeredQuestion = new AnsweredQuestion({
|
|
22
|
+
id_project,
|
|
23
|
+
namespace,
|
|
24
|
+
question,
|
|
25
|
+
answer,
|
|
26
|
+
tokens,
|
|
27
|
+
request_id,
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
return await answeredQuestion.save();
|
|
31
|
+
|
|
32
|
+
} catch (error) {
|
|
33
|
+
throw error;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async createUnansweredQuestion(id_project, data) {
|
|
38
|
+
try {
|
|
39
|
+
const { namespace, question, request_id, sender } = data;
|
|
40
|
+
|
|
41
|
+
if (!namespace || !question) {
|
|
42
|
+
throw new Error({ status: 422, error: 'Missing required parameters: namespace and question' });
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const isValidNamespace = await this.validateNamespace(id_project, namespace);
|
|
46
|
+
if (!isValidNamespace) {
|
|
47
|
+
throw new Error({ status: 403, error: 'Not allowed. The namespace does not belong to the current project.' });
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const unansweredQuestion = new UnansweredQuestion({
|
|
51
|
+
id_project,
|
|
52
|
+
namespace,
|
|
53
|
+
question,
|
|
54
|
+
request_id,
|
|
55
|
+
sender,
|
|
56
|
+
});
|
|
57
|
+
return await unansweredQuestion.save();
|
|
58
|
+
|
|
59
|
+
} catch (error) {
|
|
60
|
+
throw error;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
async validateNamespace(id_project, namespace_id) {
|
|
65
|
+
try {
|
|
66
|
+
const namespace = await Namespace.findOne({
|
|
67
|
+
id_project: id_project,
|
|
68
|
+
id: namespace_id
|
|
69
|
+
});
|
|
70
|
+
return !!namespace;
|
|
71
|
+
} catch (error) {
|
|
72
|
+
throw error;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async trackKbQaResult(id_project, { namespace, question }, answer, tokens) {
|
|
77
|
+
try {
|
|
78
|
+
if (answer.success === true) {
|
|
79
|
+
await this.createAnsweredQuestion(id_project, {
|
|
80
|
+
namespace,
|
|
81
|
+
question,
|
|
82
|
+
answer: answer.answer,
|
|
83
|
+
tokens,
|
|
84
|
+
});
|
|
85
|
+
} else if (answer.success === false) {
|
|
86
|
+
await this.createUnansweredQuestion(id_project, { namespace, question });
|
|
87
|
+
} else {
|
|
88
|
+
winston.warn('qa answer.success is not true or false: ', answer.success);
|
|
89
|
+
}
|
|
90
|
+
} catch (error) {
|
|
91
|
+
winston.error('qa err: ', error);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const kbQuestionService = new KbQuestionService();
|
|
98
|
+
module.exports = kbQuestionService;
|
package/test/kbRoute.js
CHANGED
|
@@ -8,6 +8,7 @@ process.env.PINECONE_TYPE = "serverless";
|
|
|
8
8
|
process.env.PINECONE_INDEX_HYBRID = "test-index-hybrid";
|
|
9
9
|
process.env.PINECONE_TYPE_HYBRID = "serverless";
|
|
10
10
|
process.env.ADMIN_EMAIL = "admin@tiledesk.com";
|
|
11
|
+
process.env.KB_ENDPOINT_TRAIN = "http://kb-train.test";
|
|
11
12
|
|
|
12
13
|
var userService = require('../services/userService');
|
|
13
14
|
var projectService = require('../services/projectService');
|
|
@@ -27,6 +28,8 @@ const path = require('path');
|
|
|
27
28
|
const mongoose = require('mongoose');
|
|
28
29
|
const nock = require('nock');
|
|
29
30
|
const faq = require('../models/faq');
|
|
31
|
+
const { Namespace } = require('../models/kb_setting');
|
|
32
|
+
const default_engine = require('../config/kb/engine');
|
|
30
33
|
|
|
31
34
|
|
|
32
35
|
// chai.config.includeStack = true;
|
|
@@ -85,6 +88,7 @@ describe('KbRoute', () => {
|
|
|
85
88
|
expect(res.body[0].embedding.provider).to.equal('openai')
|
|
86
89
|
expect(res.body[0].embedding.name).to.equal('text-embedding-ada-002')
|
|
87
90
|
expect(res.body[0].embedding.dimension).to.equal(1536)
|
|
91
|
+
expect(res.body[0].embedding.api_key).to.equal('')
|
|
88
92
|
|
|
89
93
|
done();
|
|
90
94
|
})
|
|
@@ -125,6 +129,7 @@ describe('KbRoute', () => {
|
|
|
125
129
|
expect(res.body.embedding.provider).to.equal('openai')
|
|
126
130
|
expect(res.body.embedding.name).to.equal('text-embedding-ada-002')
|
|
127
131
|
expect(res.body.embedding.dimension).to.equal(1536)
|
|
132
|
+
expect(res.body.embedding.api_key).to.equal('')
|
|
128
133
|
|
|
129
134
|
// Get again all namespace. A new default namespace should not be created.
|
|
130
135
|
chai.request(server)
|
|
@@ -140,6 +145,7 @@ describe('KbRoute', () => {
|
|
|
140
145
|
expect(res.body.length).to.equal(1);
|
|
141
146
|
should.not.exist(res.body[0]._id);
|
|
142
147
|
should.exist(res.body[0].id);
|
|
148
|
+
expect(res.body[0].embedding.api_key).to.equal('');
|
|
143
149
|
|
|
144
150
|
done();
|
|
145
151
|
})
|
|
@@ -237,6 +243,7 @@ describe('KbRoute', () => {
|
|
|
237
243
|
expect(res.body.embedding.provider).to.equal('openai')
|
|
238
244
|
expect(res.body.embedding.name).to.equal('text-embedding-ada-002')
|
|
239
245
|
expect(res.body.embedding.dimension).to.equal(1536)
|
|
246
|
+
expect(res.body.embedding.api_key).to.equal('')
|
|
240
247
|
|
|
241
248
|
done();
|
|
242
249
|
})
|
|
@@ -284,6 +291,9 @@ describe('KbRoute', () => {
|
|
|
284
291
|
res.body.should.be.a('object');
|
|
285
292
|
expect(res.body.success).to.equal(true);
|
|
286
293
|
expect(res.body.message).to.equal("Contents imported successfully");
|
|
294
|
+
res.body.schedule_json.should.be.a('array');
|
|
295
|
+
expect(res.body.schedule_json.length).to.equal(3);
|
|
296
|
+
expect(res.body.schedule_json[0].embedding.api_key).to.equal('fakegptkey');
|
|
287
297
|
|
|
288
298
|
chai.request(server)
|
|
289
299
|
.get('/' + savedProject._id + '/kb/?namespace=' + namespace_id)
|
|
@@ -305,7 +315,22 @@ describe('KbRoute', () => {
|
|
|
305
315
|
let content_without_tags = res.body.kbs.find(kb => kb.source !== 'Example content');
|
|
306
316
|
expect(content_without_tags.tags).to.equal(undefined);
|
|
307
317
|
|
|
308
|
-
|
|
318
|
+
chai.request(server)
|
|
319
|
+
.get('/' + savedProject._id + '/kb/namespace/all')
|
|
320
|
+
.auth(email, pwd)
|
|
321
|
+
.end((err, res) => {
|
|
322
|
+
if (err) { console.error("err: ", err); }
|
|
323
|
+
if (log) { console.log("get all namespaces res.body: ", res.body); }
|
|
324
|
+
|
|
325
|
+
res.should.have.status(200);
|
|
326
|
+
res.body.should.be.a('array');
|
|
327
|
+
expect(res.body.length).to.equal(1);
|
|
328
|
+
expect(res.body[0].id).to.equal(namespace_id);
|
|
329
|
+
expect(res.body[0].name).to.equal("Default");
|
|
330
|
+
expect(res.body[0].embedding.api_key).to.equal('');
|
|
331
|
+
|
|
332
|
+
done();
|
|
333
|
+
})
|
|
309
334
|
})
|
|
310
335
|
|
|
311
336
|
})
|
|
@@ -370,6 +395,7 @@ describe('KbRoute', () => {
|
|
|
370
395
|
expect(res.body.preview_settings.max_tokens).to.equal(256)
|
|
371
396
|
expect(res.body.preview_settings.temperature).to.equal(0.3)
|
|
372
397
|
expect(res.body.preview_settings.top_k).to.equal(6)
|
|
398
|
+
expect(res.body.embedding.api_key).to.equal('')
|
|
373
399
|
|
|
374
400
|
done();
|
|
375
401
|
|
|
@@ -379,6 +405,43 @@ describe('KbRoute', () => {
|
|
|
379
405
|
});
|
|
380
406
|
})
|
|
381
407
|
|
|
408
|
+
it('embedding-api-key-never-persisted', (done) => {
|
|
409
|
+
const namespaceId = new mongoose.Types.ObjectId().toString();
|
|
410
|
+
const projectId = new mongoose.Types.ObjectId().toString();
|
|
411
|
+
|
|
412
|
+
const ns = new Namespace({
|
|
413
|
+
id_project: projectId,
|
|
414
|
+
id: namespaceId,
|
|
415
|
+
name: 'ApiKeyTest',
|
|
416
|
+
preview_settings: {
|
|
417
|
+
model: 'gpt-4o',
|
|
418
|
+
max_tokens: 256,
|
|
419
|
+
temperature: 0.7,
|
|
420
|
+
top_k: 4,
|
|
421
|
+
context: null
|
|
422
|
+
},
|
|
423
|
+
engine: default_engine,
|
|
424
|
+
embedding: {
|
|
425
|
+
provider: 'openai',
|
|
426
|
+
name: 'text-embedding-ada-002',
|
|
427
|
+
dimension: 1536,
|
|
428
|
+
api_key: 'must-not-persist'
|
|
429
|
+
}
|
|
430
|
+
});
|
|
431
|
+
|
|
432
|
+
ns.save()
|
|
433
|
+
.then((saved) => {
|
|
434
|
+
expect(saved.embedding.api_key).to.equal('');
|
|
435
|
+
return Namespace.findOne({ id: namespaceId }).lean();
|
|
436
|
+
})
|
|
437
|
+
.then((doc) => {
|
|
438
|
+
expect(doc.embedding.api_key).to.equal('');
|
|
439
|
+
return Namespace.deleteOne({ _id: doc._id });
|
|
440
|
+
})
|
|
441
|
+
.then(() => done())
|
|
442
|
+
.catch(done);
|
|
443
|
+
})
|
|
444
|
+
|
|
382
445
|
/**
|
|
383
446
|
* Delete default namespace - Forbidden
|
|
384
447
|
*/
|
|
@@ -515,7 +578,6 @@ describe('KbRoute', () => {
|
|
|
515
578
|
|
|
516
579
|
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
|
517
580
|
projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
|
|
518
|
-
|
|
519
581
|
chai.request(server)
|
|
520
582
|
.get('/' + savedProject._id + '/kb/namespace/all')
|
|
521
583
|
.auth(email, pwd)
|
|
@@ -579,6 +641,7 @@ describe('KbRoute', () => {
|
|
|
579
641
|
expect(scheduleJson.tags[1]).to.equal("example");
|
|
580
642
|
should.exist(scheduleJson.engine)
|
|
581
643
|
should.exist(scheduleJson.embedding)
|
|
644
|
+
expect(scheduleJson.embedding.api_key).to.equal('fakegptkey');
|
|
582
645
|
|
|
583
646
|
done();
|
|
584
647
|
})
|
|
@@ -632,7 +695,6 @@ describe('KbRoute', () => {
|
|
|
632
695
|
res.body.should.be.a('object');
|
|
633
696
|
|
|
634
697
|
let realResponse = res.body.data;
|
|
635
|
-
console.log("realResponse: ", realResponse);
|
|
636
698
|
expect(realResponse.value.id_project).to.equal(namespace_id)
|
|
637
699
|
expect(realResponse.value.name).to.equal("example_text1")
|
|
638
700
|
expect(realResponse.value.type).to.equal("text")
|
|
@@ -652,6 +714,83 @@ describe('KbRoute', () => {
|
|
|
652
714
|
|
|
653
715
|
})
|
|
654
716
|
|
|
717
|
+
it('update-content', (done) => {
|
|
718
|
+
const kbTrainUrl = process.env.KB_ENDPOINT_TRAIN;
|
|
719
|
+
|
|
720
|
+
const deleteScope = nock(kbTrainUrl)
|
|
721
|
+
.post('/delete/id')
|
|
722
|
+
.reply(200, { success: true });
|
|
723
|
+
|
|
724
|
+
var email = "test-signup-" + Date.now() + "@email.com";
|
|
725
|
+
var pwd = "pwd";
|
|
726
|
+
|
|
727
|
+
userService.signup(email, pwd, "Test Firstname", "Test lastname").then(function (savedUser) {
|
|
728
|
+
projectService.create("test-faqkb-create", savedUser._id).then(function (savedProject) {
|
|
729
|
+
|
|
730
|
+
chai.request(server)
|
|
731
|
+
.get('/' + savedProject._id + '/kb/namespace/all')
|
|
732
|
+
.auth(email, pwd)
|
|
733
|
+
.end((err, res) => {
|
|
734
|
+
if (err) { console.error("err: ", err); }
|
|
735
|
+
|
|
736
|
+
res.should.have.status(200);
|
|
737
|
+
let namespace_id = res.body[0].id;
|
|
738
|
+
|
|
739
|
+
let kb = {
|
|
740
|
+
name: "example_text_update",
|
|
741
|
+
type: "text",
|
|
742
|
+
source: "example_text_update",
|
|
743
|
+
content: "Original text",
|
|
744
|
+
namespace: namespace_id
|
|
745
|
+
};
|
|
746
|
+
|
|
747
|
+
chai.request(server)
|
|
748
|
+
.post('/' + savedProject._id + '/kb')
|
|
749
|
+
.auth(email, pwd)
|
|
750
|
+
.send(kb)
|
|
751
|
+
.end((err, res) => {
|
|
752
|
+
if (err) { console.error("err: ", err); }
|
|
753
|
+
|
|
754
|
+
res.should.have.status(200);
|
|
755
|
+
let kb_id = res.body.data.value._id;
|
|
756
|
+
|
|
757
|
+
chai.request(server)
|
|
758
|
+
.put('/' + savedProject._id + '/kb/' + kb_id)
|
|
759
|
+
.auth(email, pwd)
|
|
760
|
+
.send({
|
|
761
|
+
name: "example_text_update",
|
|
762
|
+
type: "text",
|
|
763
|
+
source: "example_text_update",
|
|
764
|
+
content: "Updated text",
|
|
765
|
+
namespace: namespace_id
|
|
766
|
+
})
|
|
767
|
+
.end((err, res) => {
|
|
768
|
+
if (err) { console.error("err: ", err); }
|
|
769
|
+
if (log) { console.log("update content res.body: ", res.body); }
|
|
770
|
+
|
|
771
|
+
res.should.have.status(200);
|
|
772
|
+
expect(res.body.success).to.equal(true);
|
|
773
|
+
expect(res.body.message).to.equal("Schedule scrape skipped in test environment");
|
|
774
|
+
expect(res.body.data.content).to.equal("Updated text");
|
|
775
|
+
should.exist(res.body.schedule_json.embedding);
|
|
776
|
+
expect(res.body.schedule_json.embedding.api_key).to.equal('fakegptkey');
|
|
777
|
+
|
|
778
|
+
chai.request(server)
|
|
779
|
+
.get('/' + savedProject._id + '/kb/namespace/all')
|
|
780
|
+
.auth(email, pwd)
|
|
781
|
+
.end((err, res) => {
|
|
782
|
+
expect(res.body[0].embedding.api_key).to.equal('');
|
|
783
|
+
expect(deleteScope.isDone()).to.equal(true);
|
|
784
|
+
nock.cleanAll();
|
|
785
|
+
done();
|
|
786
|
+
});
|
|
787
|
+
});
|
|
788
|
+
});
|
|
789
|
+
});
|
|
790
|
+
});
|
|
791
|
+
});
|
|
792
|
+
}).timeout(10000)
|
|
793
|
+
|
|
655
794
|
it('get-content-chunks', (done) => {
|
|
656
795
|
|
|
657
796
|
var email = "test-signup-" + Date.now() + "@email.com";
|
|
@@ -1018,7 +1157,6 @@ describe('KbRoute', () => {
|
|
|
1018
1157
|
|
|
1019
1158
|
if (err) { console.error("err: ", err); }
|
|
1020
1159
|
if (log) { console.log("res.body: ", res.body) }
|
|
1021
|
-
console.log("res.body: ", res.body)
|
|
1022
1160
|
res.should.have.status(200);
|
|
1023
1161
|
res.body.should.be.a('object');
|
|
1024
1162
|
expect(res.body.success).to.equal(true);
|
|
@@ -1026,7 +1164,6 @@ describe('KbRoute', () => {
|
|
|
1026
1164
|
|
|
1027
1165
|
let realResponse = res.body.data;
|
|
1028
1166
|
realResponse.should.be.a('array');
|
|
1029
|
-
console.log("realResponse: ", realResponse[0]);
|
|
1030
1167
|
expect(realResponse.length).to.equal(2);
|
|
1031
1168
|
expect(realResponse[0].namespace).to.equal(namespace_id);
|
|
1032
1169
|
expect(realResponse[0].type).to.equal('faq');
|
|
@@ -1050,6 +1187,7 @@ describe('KbRoute', () => {
|
|
|
1050
1187
|
expect(scheduleJson[0].engine.index_name).to.equal(namespace.engine.index_name);
|
|
1051
1188
|
expect(scheduleJson[0].embedding.provider).to.equal(namespace.embedding.provider);
|
|
1052
1189
|
expect(scheduleJson[0].embedding.name).to.equal(namespace.embedding.name);
|
|
1190
|
+
expect(scheduleJson[0].embedding.api_key).to.equal('fakegptkey');
|
|
1053
1191
|
|
|
1054
1192
|
expect(scheduleJson[1].namespace).to.equal(namespace_id);
|
|
1055
1193
|
expect(scheduleJson[1].type).to.equal('faq');
|
|
@@ -1215,6 +1353,7 @@ describe('KbRoute', () => {
|
|
|
1215
1353
|
expect(scheduleJson[0].engine.index_name).to.equal(namespace.engine.index_name);
|
|
1216
1354
|
expect(scheduleJson[0].embedding.provider).to.equal(namespace.embedding.provider);
|
|
1217
1355
|
expect(scheduleJson[0].embedding.name).to.equal(namespace.embedding.name);
|
|
1356
|
+
expect(scheduleJson[0].embedding.api_key).to.equal('fakegptkey');
|
|
1218
1357
|
|
|
1219
1358
|
expect(scheduleJson[1].namespace).to.equal(namespace_id);
|
|
1220
1359
|
expect(scheduleJson[1].source).to.equal('https://gethelp.tiledesk.com/articles/article2');
|
|
@@ -1407,6 +1546,7 @@ describe('KbRoute', () => {
|
|
|
1407
1546
|
scheduleJson.should.be.a('array');
|
|
1408
1547
|
should.exist(scheduleJson[0].engine)
|
|
1409
1548
|
should.exist(scheduleJson[0].embedding)
|
|
1549
|
+
expect(scheduleJson[0].embedding.api_key).to.equal('fakegptkey');
|
|
1410
1550
|
|
|
1411
1551
|
done();
|
|
1412
1552
|
})
|
|
@@ -1485,6 +1625,7 @@ describe('KbRoute', () => {
|
|
|
1485
1625
|
expect(res.body.data.embedding.provider).to.equal("openai");
|
|
1486
1626
|
expect(res.body.data.embedding.name).to.equal("text-embedding-ada-002");
|
|
1487
1627
|
expect(res.body.data.embedding.dimension).to.equal(1536);
|
|
1628
|
+
expect(res.body.data.embedding.api_key).to.equal('fakegptkey');
|
|
1488
1629
|
|
|
1489
1630
|
done();
|
|
1490
1631
|
|
|
@@ -1759,7 +1900,7 @@ describe('KbRoute', () => {
|
|
|
1759
1900
|
.get('/' + savedProject._id + '/kb/namespace/all')
|
|
1760
1901
|
.auth(email, pwd)
|
|
1761
1902
|
.end((err, res) => {
|
|
1762
|
-
|
|
1903
|
+
|
|
1763
1904
|
if (err) { console.error("err: ", err); }
|
|
1764
1905
|
if (log) { console.log("get namespaces res.body: ", res.body); }
|
|
1765
1906
|
|
|
@@ -1778,7 +1919,7 @@ describe('KbRoute', () => {
|
|
|
1778
1919
|
.auth(email, pwd)
|
|
1779
1920
|
.send(data)
|
|
1780
1921
|
.end((err, res) => {
|
|
1781
|
-
|
|
1922
|
+
|
|
1782
1923
|
if (err) { console.error("err: ", err); }
|
|
1783
1924
|
if (log) { console.log("create unanswered question res.body: ", res.body); }
|
|
1784
1925
|
|