@tiledesk/tiledesk-server 2.19.5 → 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 CHANGED
@@ -5,7 +5,11 @@
5
5
  🚀 IN PRODUCTION 🚀
6
6
  (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
7
7
 
8
- # 2.19.5
8
+ # 2.19.6
9
+ - Improved management of answered and unanswered questions, duration and token consumption
10
+ - Improved namespace embedding management
11
+
12
+ # 2.19.5 (aborted)
9
13
  - Improved management of answered and unanswered questions, duration and token consumption
10
14
 
11
15
  # 2.19.4
@@ -20,67 +20,6 @@ let expireAnsweredAfterSeconds = ttlSecondsFromEnv(
20
20
  DEFAULT_ANSWERED_TTL_SEC
21
21
  );
22
22
 
23
- const EMPTY_EMBEDDING_API_KEY = '';
24
-
25
- function logEmbeddingApiKeyWriteAttempt(source, attemptedValue, meta = {}) {
26
- if (attemptedValue === EMPTY_EMBEDDING_API_KEY || attemptedValue == null) {
27
- return;
28
- }
29
- winston.warn('[Namespace.embedding.api_key] non-empty value blocked on ' + source, {
30
- ...meta,
31
- attemptedValue,
32
- stack: new Error().stack
33
- });
34
- }
35
-
36
- function sanitizeEmbeddingApiKeyObject(embedding, source, meta = {}) {
37
- if (!embedding || typeof embedding !== 'object') {
38
- return false;
39
- }
40
- if (!Object.prototype.hasOwnProperty.call(embedding, 'api_key')) {
41
- return false;
42
- }
43
- if (embedding.api_key === EMPTY_EMBEDDING_API_KEY || embedding.api_key == null) {
44
- embedding.api_key = EMPTY_EMBEDDING_API_KEY;
45
- return false;
46
- }
47
- logEmbeddingApiKeyWriteAttempt(source, embedding.api_key, meta);
48
- embedding.api_key = EMPTY_EMBEDDING_API_KEY;
49
- return true;
50
- }
51
-
52
- function sanitizeEmbeddingApiKeyUpdate(update, source, meta = {}) {
53
- if (!update || typeof update !== 'object') {
54
- return false;
55
- }
56
-
57
- let changed = false;
58
-
59
- const sanitizeContainer = (container) => {
60
- if (!container || typeof container !== 'object') {
61
- return;
62
- }
63
- if (sanitizeEmbeddingApiKeyObject(container.embedding, source, meta)) {
64
- changed = true;
65
- }
66
- if (Object.prototype.hasOwnProperty.call(container, 'embedding.api_key')
67
- && container['embedding.api_key'] !== EMPTY_EMBEDDING_API_KEY) {
68
- logEmbeddingApiKeyWriteAttempt(source, container['embedding.api_key'], meta);
69
- container['embedding.api_key'] = EMPTY_EMBEDDING_API_KEY;
70
- changed = true;
71
- }
72
- };
73
-
74
- sanitizeContainer(update);
75
- ['$set', '$setOnInsert'].forEach((key) => {
76
- if (update[key]) {
77
- sanitizeContainer(update[key]);
78
- }
79
- });
80
-
81
- return changed;
82
- }
83
-
84
23
 
85
24
  const EngineSchema = new Schema({
86
25
  name: {
@@ -139,11 +78,8 @@ const EmbeddingSchema = new Schema({
139
78
  api_key: {
140
79
  type: String,
141
80
  required: false,
142
- default: EMPTY_EMBEDDING_API_KEY,
143
- set: function (value) {
144
- logEmbeddingApiKeyWriteAttempt('embedding.api_key setter', value);
145
- return EMPTY_EMBEDDING_API_KEY;
146
- }
81
+ default: '',
82
+ set: () => ''
147
83
  }
148
84
  }, {
149
85
  _id: false // This is schema is always used as an embedded object inside NamespaceSchema
@@ -186,39 +122,6 @@ const NamespaceSchema = new Schema({
186
122
  timestamps: true
187
123
  })
188
124
 
189
- NamespaceSchema.pre('save', function (next) {
190
- if (this.isModified('embedding.api_key')) {
191
- const attemptedValue = this.get('embedding.api_key');
192
- logEmbeddingApiKeyWriteAttempt('save', attemptedValue, {
193
- namespaceId: this.id,
194
- id_project: this.id_project
195
- });
196
- this.set('embedding.api_key', EMPTY_EMBEDDING_API_KEY);
197
- }
198
- next();
199
- });
200
-
201
- ['updateOne', 'updateMany', 'findOneAndUpdate'].forEach((hook) => {
202
- NamespaceSchema.pre(hook, function (next) {
203
- const update = this.getUpdate();
204
- if (sanitizeEmbeddingApiKeyUpdate(update, hook, { query: this.getQuery() })) {
205
- this.setUpdate(update);
206
- }
207
- next();
208
- });
209
- });
210
-
211
- NamespaceSchema.pre('insertMany', function (next, docs) {
212
- if (Array.isArray(docs)) {
213
- docs.forEach((doc) => {
214
- sanitizeEmbeddingApiKeyObject(doc.embedding, 'insertMany', {
215
- namespaceId: doc.id,
216
- id_project: doc.id_project
217
- });
218
- });
219
- }
220
- next();
221
- });
222
125
 
223
126
  var KBSchema = new Schema({
224
127
  id_project: {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tiledesk/tiledesk-server",
3
3
  "description": "The Tiledesk server module",
4
- "version": "2.19.5",
4
+ "version": "2.19.6",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
package/routes/kb.js CHANGED
@@ -115,13 +115,6 @@ function getRagContextTemplate(modelName) {
115
115
  return ragPromptManager.getPrompt(modelName);
116
116
  }
117
117
 
118
- function normalizeEmbedding(embedding) {
119
- const normalizedEmbedding = (embedding && typeof embedding.toObject === 'function')
120
- ? embedding.toObject()
121
- : (embedding || default_embedding);
122
- return { ...normalizedEmbedding };
123
- }
124
-
125
118
  function normalizeSituatedContext(enable = false) {
126
119
  situatedContext.enable = enable;
127
120
  return situatedContext.enable
@@ -264,8 +257,7 @@ router.post('/scrape/single', async (req, res) => {
264
257
  }
265
258
 
266
259
  json.engine = namespace.engine || default_engine;
267
- json.embedding = normalizeEmbedding(namespace.embedding);
268
- json.embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
260
+ json.embedding = aiManager.normalizeEmbedding(namespace.embedding);
269
261
 
270
262
  if (namespace.hybrid === true) {
271
263
  json.hybrid = true;
@@ -412,8 +404,7 @@ router.post('/qa', async (req, res) => {
412
404
  }
413
405
 
414
406
  data.engine = namespace.engine || default_engine;
415
- data.embedding = normalizeEmbedding(namespace.embedding);
416
- data.embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
407
+ data.embedding = aiManager.normalizeEmbedding(namespace.embedding);
417
408
 
418
409
  if (namespace.hybrid === true) {
419
410
  data.search_type = 'hybrid';
@@ -1298,8 +1289,7 @@ router.post('/namespace/import/:id', upload.single('uploadFile'), async (req, re
1298
1289
  // import operation the content's limit is respected
1299
1290
  let ns = namespaces.find(n => n.id === namespace_id);
1300
1291
  let engine = ns.engine || default_engine;
1301
- let embedding = normalizeEmbedding(ns.embedding);
1302
- embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
1292
+ let embedding = aiManager.normalizeEmbedding(ns.embedding);
1303
1293
  let hybrid = ns.hybrid;
1304
1294
  const situated_context = normalizeSituatedContext();
1305
1295
 
@@ -1355,6 +1345,10 @@ router.post('/namespace/import/:id', upload.single('uploadFile'), async (req, re
1355
1345
  aiManager.scheduleScrape(resources, hybrid);
1356
1346
  }
1357
1347
 
1348
+ if (process.env.NODE_ENV === "test") {
1349
+ return res.status(200).send({ success: true, message: "Contents imported successfully", schedule_json: resources });
1350
+ }
1351
+
1358
1352
  res.status(200).send({ success: true, message: "Contents imported successfully" });
1359
1353
 
1360
1354
 
@@ -1731,8 +1725,7 @@ router.post('/', async (req, res) => {
1731
1725
 
1732
1726
  const saved_kb = raw_content.value;
1733
1727
  const webhook = apiUrl + '/webhook/kb/status?token=' + KB_WEBHOOK_TOKEN;
1734
- const embedding = normalizeEmbedding(namespace.embedding);
1735
- embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
1728
+ const embedding = aiManager.normalizeEmbedding(namespace.embedding);
1736
1729
 
1737
1730
  const situated_context_obj = normalizeSituatedContext(saved_kb.situated_context);
1738
1731
 
@@ -1908,8 +1901,7 @@ router.post('/csv', upload.single('uploadFile'), async (req, res) => {
1908
1901
  aiManager.saveBulk(operations, kbs, project_id, namespace_id).then((result) => {
1909
1902
 
1910
1903
  let engine = namespace.engine || default_engine;
1911
- let embedding = normalizeEmbedding(namespace.embedding);
1912
- embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
1904
+ let embedding = aiManager.normalizeEmbedding(namespace.embedding);
1913
1905
  let hybrid = namespace.hybrid;
1914
1906
 
1915
1907
  let situated_context_obj;
@@ -1965,7 +1957,7 @@ router.post('/sitemap', async (req, res) => {
1965
1957
  winston.debug("data: ", data);
1966
1958
  res.status(200).send(data);
1967
1959
  }).catch((err) => {
1968
- console.error("err ", err)
1960
+ winston.error("Error fetching sitemap: ", err)
1969
1961
  res.status(500).send({ success: false, error: err });
1970
1962
  })
1971
1963
 
@@ -2202,8 +2194,7 @@ router.put('/:kb_id', async (req, res) => {
2202
2194
  return res.status(500).send({ success: false, error: err });
2203
2195
  }
2204
2196
 
2205
- const embedding = normalizeEmbedding(namespace.embedding);
2206
- embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
2197
+ const embedding = aiManager.normalizeEmbedding(namespace.embedding);
2207
2198
  let webhook = apiUrl + '/webhook/kb/status?token=' + KB_WEBHOOK_TOKEN;
2208
2199
  const situated_context_obj = normalizeSituatedContext(updated_content.situated_context);
2209
2200
 
@@ -2263,7 +2254,7 @@ router.delete('/:kb_id', async (req, res) => {
2263
2254
  if (kb.type === 'sitemap') {
2264
2255
  try {
2265
2256
  await aiManager.deleteSitemap(kb, namespace);
2266
- console.log("Scheduled jobs for deleting sitemap");
2257
+ winston.info("Scheduled jobs for deleting sitemap");
2267
2258
  //return res.status(200).send({ success: true, message: "Scheduled jobs for deleting sitemap" });
2268
2259
  } catch (err) {
2269
2260
  winston.error("Error deleting sitemap: ", err);
@@ -3,7 +3,7 @@ const router = express.Router();
3
3
  const { Namespace, UnansweredQuestion } = require('../models/kb_setting');
4
4
  var winston = require('../config/winston');
5
5
  var fastCsv = require('fast-csv');
6
- const { KbQuestionService } = require('../services/kbQuestionService');
6
+ const kbQuestionService = require('../services/kbQuestionService');
7
7
 
8
8
  // Add a new unanswered question
9
9
  router.post('/', async (req, res) => {
@@ -11,7 +11,7 @@ router.post('/', async (req, res) => {
11
11
  const data = req.body;
12
12
  const id_project = req.projectid;
13
13
 
14
- const savedQuestion = await KbQuestionService.createUnansweredQuestion(
14
+ const savedQuestion = await kbQuestionService.createUnansweredQuestion(
15
15
  id_project,
16
16
  data
17
17
  );
package/routes/webhook.js CHANGED
@@ -199,8 +199,7 @@ router.post('/kb/reindex', async (req, res) => {
199
199
  json.engine = namespace.engine || (namespace.hybrid ? default_engine_hybrid : default_engine);
200
200
  json.hybrid = namespace.hybrid;
201
201
 
202
- let embedding = namespace.embedding || Object.assign({}, default_embedding);
203
- embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
202
+ let embedding = aiManager.normalizeEmbedding(namespace.embedding);
204
203
  json.embedding = embedding;
205
204
 
206
205
  const situated_context_obj = aiManager.normalizeSituatedContext(kb.situated_context);
@@ -95,8 +95,7 @@ class AiManager {
95
95
  this.saveBulk(operations, kbs, namespace.id_project, namespace.id).then( async (result) => {
96
96
  let hybrid = namespace.hybrid;
97
97
  let engine = namespace.engine || default_engine;
98
- let embedding = namespace.embedding || Object.assign({}, default_embedding);
99
- embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
98
+ let embedding = this.normalizeEmbedding(namespace.embedding);
100
99
 
101
100
  let situated_context;
102
101
  if (options.situated_context) {
@@ -146,7 +145,7 @@ class AiManager {
146
145
  namespace: namespace.id,
147
146
  refresh_rate: options.refresh_rate,
148
147
  engine: namespace.engine,
149
- embedding: namespace.embedding,
148
+ embedding: this.normalizeEmbedding(namespace.embedding),
150
149
  hybrid: namespace.hybrid,
151
150
  ...(options.situated_context && { situated_context: options.situated_context }),
152
151
  }
@@ -449,7 +448,7 @@ class AiManager {
449
448
  if (err) {
450
449
  winston.error("deleteSitemap: deleteSchedule error for kb " + kb._id, err);
451
450
  }
452
- console.log("deleteSitemap: deleteSchedule result for kb " + kb._id, result);
451
+ winston.info("deleteSitemap: deleteSchedule result for kb " + kb._id, result);
453
452
  resolve(result);
454
453
  });
455
454
  });
@@ -597,6 +596,16 @@ class AiManager {
597
596
  })
598
597
  }
599
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
+
600
609
  normalizeSituatedContext(enable = false) {
601
610
  situatedContext.enable = enable;
602
611
  return situatedContext.enable
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
- done();
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