@tiledesk/tiledesk-server 2.18.3 → 2.18.4

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,6 +5,12 @@
5
5
  🚀 IN PRODUCTION 🚀
6
6
  (https://www.npmjs.com/package/@tiledesk/tiledesk-server/v/2.3.77)
7
7
 
8
+ # 2.18.4
9
+ - Added HyDE support for Knowledge Base Q&A
10
+ - Introduced Cache (cRag) functionality in Knowledge Base Q&A
11
+ - Enabled Situated Context for enhanced Knowledge Base content indexing
12
+ - Bumped tybot-connector version to 2.0.48
13
+
8
14
  # 2.18.3
9
15
  - Added permissions logic
10
16
  - Added custom roles support
@@ -1,6 +1,6 @@
1
1
  module.exports = {
2
2
  enable: process.env.SITUATED_CONTEXT_ENABLE === "true",
3
3
  provider: process.env.SITUATED_CONTEXT_PROVIDER || "openai",
4
- model: process.env.SITUATED_CONTEXT_MODEL || "gpt-4o",
4
+ model: process.env.SITUATED_CONTEXT_MODEL || "gpt-5.4-nano",
5
5
  api_key: ""
6
6
  }
@@ -198,6 +198,11 @@ var KBSchema = new Schema({
198
198
  type: Array,
199
199
  default: undefined,
200
200
  required: false
201
+ },
202
+ situated_context: {
203
+ type: Boolean,
204
+ default: false,
205
+ required: false
201
206
  }
202
207
  }, {
203
208
  timestamps: true
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.18.3",
4
+ "version": "2.18.4",
5
5
  "scripts": {
6
6
  "start": "node ./bin/www",
7
7
  "pretest": "mongodb-runner start",
@@ -49,7 +49,7 @@
49
49
  "@tiledesk/tiledesk-rasa-connector": "^1.0.10",
50
50
  "@tiledesk/tiledesk-sms-connector": "^0.1.13",
51
51
  "@tiledesk/tiledesk-telegram-connector": "^0.1.14",
52
- "@tiledesk/tiledesk-tybot-connector": "^2.0.45",
52
+ "@tiledesk/tiledesk-tybot-connector": "^2.0.48",
53
53
  "@tiledesk/tiledesk-voice-twilio-connector": "^0.3.2",
54
54
  "@tiledesk/tiledesk-vxml-connector": "^0.1.91",
55
55
  "@tiledesk/tiledesk-whatsapp-connector": "1.0.26",
package/routes/kb.js CHANGED
@@ -121,7 +121,8 @@ function normalizeEmbedding(embedding) {
121
121
  return { ...normalizedEmbedding };
122
122
  }
123
123
 
124
- function normalizeSituatedContext() {
124
+ function normalizeSituatedContext(enable = false) {
125
+ situatedContext.enable = enable;
125
126
  return situatedContext.enable
126
127
  ? {
127
128
  ...situatedContext,
@@ -199,6 +200,11 @@ router.post('/scrape/single', async (req, res) => {
199
200
  })
200
201
  }
201
202
 
203
+ let situated_context;
204
+ if (sitemapKb.situated_context && sitemapKb.situated_context === true && sitemapKb.scrape_type === 0) {
205
+ situated_context = normalizeSituatedContext(true);
206
+ }
207
+
202
208
  if (addedUrls.length > 0) {
203
209
  const options = {
204
210
  sitemap_origin_id: sitemapKb._id,
@@ -206,7 +212,8 @@ router.post('/scrape/single', async (req, res) => {
206
212
  scrape_type: sitemapKb.scrape_type,
207
213
  scrape_options: sitemapKb.scrape_options,
208
214
  refresh_rate: sitemapKb.refresh_rate,
209
- tags: sitemapKb.tags
215
+ tags: sitemapKb.tags,
216
+ ...(situated_context && { situated_context: situated_context }),
210
217
  }
211
218
  aiManager.addMultipleUrls(namespace, addedUrls, options).catch((err) => {
212
219
  winston.error("(webhook) error adding multiple urls contents: ", err);
@@ -263,9 +270,8 @@ router.post('/scrape/single', async (req, res) => {
263
270
  json.hybrid = true;
264
271
  }
265
272
 
266
- const situated_context = normalizeSituatedContext();
267
- if (situated_context) {
268
- json.situated_context = situated_context;
273
+ if (json.situated_context && json.situated_context === true && json.scrape_type === 0) {
274
+ json.situated_context = normalizeSituatedContext(true);
269
275
  }
270
276
 
271
277
  winston.verbose("/scrape/single json: ", json);
@@ -447,12 +453,11 @@ router.post('/qa', async (req, res) => {
447
453
  }
448
454
 
449
455
  data.stream = data.stream === true;
456
+ data.use_hyde = data.use_hyde === true;
457
+ data.use_cache = data.use_cache === true;
450
458
  data.debug = true;
451
459
  delete data.advancedPrompt;
452
460
  winston.verbose("ask data: ", data);
453
-
454
- console.log("data: ", data);
455
-
456
461
  if (process.env.NODE_ENV === 'test') {
457
462
  return res.status(200).send({ success: true, message: "Question skipped in test environment", data: data });
458
463
  }
@@ -1591,7 +1596,7 @@ router.post('/', async (req, res) => {
1591
1596
  const id_project = req.projectid;
1592
1597
  const project = req.project
1593
1598
 
1594
- const { name, type, source, content, refresh_rate, scrape_type, scrape_options, tags } = req.body;
1599
+ const { name, type, source, content, refresh_rate, scrape_type, scrape_options, tags, situated_context } = req.body;
1595
1600
  const namespace_id = req.body?.namespace;
1596
1601
 
1597
1602
  if (!namespace_id) {
@@ -1643,6 +1648,10 @@ router.post('/', async (req, res) => {
1643
1648
  new_kb.tags = tags;
1644
1649
  }
1645
1650
 
1651
+ if (situated_context && situated_context === true && (type !== "url" || scrape_type === 0)) {
1652
+ new_kb.situated_context = situated_context;
1653
+ }
1654
+
1646
1655
  winston.debug("adding kb: ", new_kb);
1647
1656
 
1648
1657
  KB.findOneAndUpdate({ id_project, type, source }, new_kb, { upsert: true, new: true, rawResult: true }, async (err, raw_content) => {
@@ -1661,7 +1670,7 @@ router.post('/', async (req, res) => {
1661
1670
  const embedding = normalizeEmbedding(namespace.embedding);
1662
1671
  embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
1663
1672
 
1664
- const situated_context = normalizeSituatedContext();
1673
+ const situated_context_obj = normalizeSituatedContext(saved_kb.situated_context);
1665
1674
 
1666
1675
  const json = {
1667
1676
  id: saved_kb._id,
@@ -1673,7 +1682,7 @@ router.post('/', async (req, res) => {
1673
1682
  hybrid: namespace.hybrid,
1674
1683
  engine: namespace.engine || default_engine,
1675
1684
  embedding: embedding,
1676
- ...(situated_context && { situated_context: situated_context }),
1685
+ ...(situated_context_obj && { situated_context: situated_context_obj }),
1677
1686
  ...(saved_kb.scrape_type && { scrape_type: saved_kb.scrape_type }),
1678
1687
  ...(saved_kb.scrape_options && { parameters_scrape_type_4: saved_kb.scrape_options }),
1679
1688
  ...(saved_kb.tags && { tags: saved_kb.tags }),
@@ -1705,7 +1714,7 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
1705
1714
 
1706
1715
  const id_project = req.projectid;
1707
1716
  const project = req.project;
1708
- let { refresh_rate = 'never', scrape_type = 2, scrape_options } = req.body;
1717
+ let { refresh_rate = 'never', scrape_type = 2, scrape_options, situated_context } = req.body;
1709
1718
  let tags = parseStringArrayField(req.body.tags);
1710
1719
 
1711
1720
 
@@ -1748,6 +1757,7 @@ router.post('/multi', upload.single('uploadFile'), async (req, res) => {
1748
1757
  scrape_type,
1749
1758
  scrape_options,
1750
1759
  refresh_rate,
1760
+ ...(situated_context && situated_context === true && scrape_type === 0 ? { situated_context: true } : {}),
1751
1761
  ...(Array.isArray(tags) && tags.length > 0 ? { tags } : {})
1752
1762
  }
1753
1763
 
@@ -1772,6 +1782,11 @@ router.post('/csv', upload.single('uploadFile'), async (req, res) => {
1772
1782
  const { delimiter = ';' } = req.body;
1773
1783
  let tags = parseStringArrayField(req.body.tags);
1774
1784
 
1785
+ let situated_context = false;
1786
+ if (req.body.situated_context) {
1787
+ situated_context = req.body.situated_context === true || req.body.situated_context === "true";
1788
+ }
1789
+
1775
1790
 
1776
1791
  let namespace;
1777
1792
  try {
@@ -1799,6 +1814,7 @@ router.post('/csv', upload.single('uploadFile'), async (req, res) => {
1799
1814
  content: question + "\n" + answer,
1800
1815
  namespace: namespace_id,
1801
1816
  status: -1,
1817
+ ...(situated_context && { situated_context: situated_context }),
1802
1818
  ...(Array.isArray(tags) && tags.length > 0 ? { tags } : {})
1803
1819
  })
1804
1820
  })
@@ -1830,16 +1846,20 @@ router.post('/csv', upload.single('uploadFile'), async (req, res) => {
1830
1846
  let embedding = normalizeEmbedding(namespace.embedding);
1831
1847
  embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
1832
1848
  let hybrid = namespace.hybrid;
1833
- const situated_context = normalizeSituatedContext();
1834
1849
 
1835
- let resources = result.map(({ name, status, __v, createdAt, updatedAt, id_project, ...keepAttrs }) => keepAttrs)
1850
+ let situated_context_obj;
1851
+ if (situated_context) {
1852
+ situated_context_obj = normalizeSituatedContext(situated_context);
1853
+ }
1854
+
1855
+ let resources = result.map(({ name, status, __v, createdAt, updatedAt, id_project, situated_context, ...keepAttrs }) => keepAttrs)
1836
1856
  resources = resources.map(({ _id, ...rest}) => {
1837
1857
  return {
1838
1858
  id: _id,
1839
1859
  webhook: webhook,
1840
1860
  embedding: embedding,
1841
1861
  engine: engine,
1842
- ...(situated_context && { situated_context: situated_context }),
1862
+ ...(situated_context_obj && { situated_context: situated_context_obj }),
1843
1863
  ...rest
1844
1864
  };
1845
1865
  })
@@ -1891,7 +1911,7 @@ router.post('/sitemap/import', async (req, res) => {
1891
1911
  const id_project = req.projectid;
1892
1912
  const namespace_id = req.query.namespace;
1893
1913
 
1894
- let { type, source, refresh_rate = 'never', scrape_type = 2, scrape_options, tags } = req.body;
1914
+ let { type, source, refresh_rate = 'never', scrape_type = 2, scrape_options, tags, situated_context } = req.body;
1895
1915
  if (scrape_type === 2 && !scrape_options) {
1896
1916
  scrape_options = aiManager.setDefaultScrapeOptions();
1897
1917
  }
@@ -1957,6 +1977,7 @@ router.post('/sitemap/import', async (req, res) => {
1957
1977
  scrape_type,
1958
1978
  scrape_options,
1959
1979
  refresh_rate,
1980
+ ...(situated_context && situated_context === true && scrape_type === 0 ? { situated_context: true } : {}),
1960
1981
  ...(Array.isArray(tags) && tags.length > 0 ? { tags } : {})
1961
1982
  }
1962
1983
 
@@ -1974,7 +1995,8 @@ router.post('/sitemap/import', async (req, res) => {
1974
1995
  scrape_type,
1975
1996
  scrape_options,
1976
1997
  refresh_rate,
1977
- ...(Array.isArray(tags) && tags.length > 0 ? { tags } : {})
1998
+ ...(Array.isArray(tags) && tags.length > 0 ? { tags } : {}),
1999
+ ...(situated_context && situated_context === true && scrape_type === 0 ? { situated_context: true } : {}),
1978
2000
  }
1979
2001
 
1980
2002
  try {
@@ -1998,7 +2020,7 @@ router.put('/:kb_id', async (req, res) => {
1998
2020
  const project = req.project;
1999
2021
  const kb_id = req.params.kb_id;
2000
2022
 
2001
- const { name, type, source, content, refresh_rate, scrape_type, scrape_options, tags } = req.body;
2023
+ const { name, type, source, content, refresh_rate, scrape_type, scrape_options, tags, situated_context } = req.body;
2002
2024
  const namespace_id = req.body.namespace;
2003
2025
 
2004
2026
  if (!namespace_id) {
@@ -2065,6 +2087,10 @@ router.put('/:kb_id', async (req, res) => {
2065
2087
  return res.status(500).send({ success: false, error: err });
2066
2088
  }
2067
2089
 
2090
+ if (situated_context && situated_context === true && scrape_type === 0) {
2091
+ situated_context = true;
2092
+ }
2093
+
2068
2094
  let new_content = {
2069
2095
  id_project,
2070
2096
  name,
@@ -2096,6 +2122,10 @@ router.put('/:kb_id', async (req, res) => {
2096
2122
  new_content.tags = tags;
2097
2123
  }
2098
2124
 
2125
+ if (situated_context && situated_context === true && scrape_type === 0) {
2126
+ new_content.situated_context = situated_context;
2127
+ }
2128
+
2099
2129
  winston.debug("Update content. New content: ", new_content);
2100
2130
 
2101
2131
  let updated_content;
@@ -2109,7 +2139,7 @@ router.put('/:kb_id', async (req, res) => {
2109
2139
  const embedding = normalizeEmbedding(namespace.embedding);
2110
2140
  embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
2111
2141
  let webhook = apiUrl + '/webhook/kb/status?token=' + KB_WEBHOOK_TOKEN;
2112
- const situated_context = normalizeSituatedContext();
2142
+ const situated_context_obj = normalizeSituatedContext(updated_content.situated_context);
2113
2143
 
2114
2144
  const json = {
2115
2145
  id: updated_content._id,
@@ -2121,7 +2151,7 @@ router.put('/:kb_id', async (req, res) => {
2121
2151
  hybrid: namespace.hybrid,
2122
2152
  engine: namespace.engine || default_engine,
2123
2153
  embedding: embedding,
2124
- ...(situated_context && { situated_context: situated_context }),
2154
+ ...(situated_context_obj && { situated_context: situated_context_obj }),
2125
2155
  ...(updated_content.scrape_type && { scrape_type: updated_content.scrape_type }),
2126
2156
  ...(updated_content.scrape_options && { parameters_scrape_type_4: updated_content.scrape_options }),
2127
2157
  ...(updated_content.tags && { tags: updated_content.tags }),
package/routes/webhook.js CHANGED
@@ -148,7 +148,11 @@ router.post('/kb/reindex', async (req, res) => {
148
148
  sitemap_origin: kb.source,
149
149
  scrape_type: kb.scrape_type,
150
150
  scrape_options: kb.scrape_options,
151
- refresh_rate: kb.refresh_rate
151
+ refresh_rate: kb.refresh_rate,
152
+ ...(kb.tags ? { tags: kb.tags } : {}),
153
+ ...(kb.situated_context === true && (kb.scrape_type === 0 || kb.scrape_type === '0')
154
+ ? { situated_context: true }
155
+ : {}),
152
156
  }
153
157
  aiManager.addMultipleUrls(namespace, addedUrls, options).catch((err) => {
154
158
  winston.error("(webhook) error adding multiple urls contents: ", err);
@@ -198,9 +202,9 @@ router.post('/kb/reindex', async (req, res) => {
198
202
  embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
199
203
  json.embedding = embedding;
200
204
 
201
- const situated_context = aiManager.normalizeSituatedContext();
202
- if (situated_context) {
203
- json.situated_context = situated_context;
205
+ const situated_context_obj = aiManager.normalizeSituatedContext(kb.situated_context);
206
+ if (situated_context_obj) {
207
+ json.situated_context = situated_context_obj;
204
208
  }
205
209
 
206
210
  let resources = [];
@@ -52,6 +52,7 @@ jobManagerHybrid.connectAndStartPublisher((status, error) => {
52
52
  }
53
53
  });
54
54
 
55
+
55
56
  class AiManager {
56
57
 
57
58
  constructor() { }
@@ -74,6 +75,7 @@ class AiManager {
74
75
  ...(options.sitemap_origin_id && { sitemap_origin_id: options.sitemap_origin_id }),
75
76
  ...(options.sitemap_origin && { sitemap_origin: options.sitemap_origin }),
76
77
  ...(options.tags && { tags: options.tags }),
78
+ ...(options.situated_context && { situated_context: options.situated_context }),
77
79
  }
78
80
  return kb;
79
81
  })
@@ -95,11 +97,14 @@ class AiManager {
95
97
  let embedding = namespace.embedding || default_embedding;
96
98
  embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
97
99
 
98
- let situated_context = this.normalizeSituatedContext();
100
+ let situated_context;
101
+ if (options.situated_context) {
102
+ situated_context = this.normalizeSituatedContext(options.situated_context);
103
+ }
99
104
 
100
105
  let webhook = apiUrl + '/webhook/kb/status?token=' + KB_WEBHOOK_TOKEN;
101
106
 
102
- let resources = result.map(({ name, status, __v, createdAt, updatedAt, id_project, ...keepAttrs }) => keepAttrs)
107
+ let resources = result.map(({ name, status, __v, createdAt, updatedAt, id_project, situated_context, ...keepAttrs }) => keepAttrs)
103
108
  resources = resources.map(({ _id, scrape_options, ...rest }) => {
104
109
  return {
105
110
  id: _id,
@@ -132,8 +137,6 @@ class AiManager {
132
137
  async scheduleSitemap(namespace, sitemap_content, options) {
133
138
  return new Promise((resolve, reject) => {
134
139
 
135
- const situated_context = this.normalizeSituatedContext();
136
-
137
140
  let kb = {
138
141
  id: sitemap_content._id,
139
142
  source: sitemap_content.source,
@@ -144,7 +147,7 @@ class AiManager {
144
147
  engine: namespace.engine,
145
148
  embedding: namespace.embedding,
146
149
  hybrid: namespace.hybrid,
147
- ...(situated_context && { situated_context }),
150
+ ...(options.situated_context && { situated_context: options.situated_context }),
148
151
  }
149
152
 
150
153
  if (process.env.NODE_ENV === 'test') {
@@ -190,6 +193,8 @@ class AiManager {
190
193
  throw err;
191
194
  }
192
195
 
196
+
197
+
193
198
  // Recreate all url contents with sitemap_origin_id
194
199
  let result;
195
200
  try {
@@ -567,7 +572,8 @@ class AiManager {
567
572
  })
568
573
  }
569
574
 
570
- normalizeSituatedContext() {
575
+ normalizeSituatedContext(enable = false) {
576
+ situatedContext.enable = enable;
571
577
  return situatedContext.enable
572
578
  ? {
573
579
  ...situatedContext,
package/test/kbRoute.js CHANGED
@@ -1011,6 +1011,7 @@ describe('KbRoute', () => {
1011
1011
  .auth(email, pwd)
1012
1012
  //.set('Content-Type', 'text/csv')
1013
1013
  .field('delimiter', ';')
1014
+ .field('situated_context', true)
1014
1015
  .field('tags', JSON.stringify(['tag1', 'tag2']))
1015
1016
  .attach('uploadFile', fs.readFileSync(path.resolve(__dirname, './fixtures/example-kb-faqs.csv')), 'example-kb-faqs.csv')
1016
1017
  .end((err, res) => {