@tiledesk/tiledesk-server 2.15.8 → 2.17.2
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 +21 -0
- package/config/kb/prompt/rag/PromptManager.js +57 -0
- package/config/kb/prompt/rag/general.txt +9 -0
- package/config/kb/prompt/rag/gpt-3.5.txt +9 -0
- package/config/kb/prompt/rag/gpt-4.1.txt +9 -0
- package/config/kb/prompt/rag/gpt-4.txt +11 -0
- package/config/kb/prompt/rag/gpt-4o.txt +9 -0
- package/config/kb/prompt/rag/gpt-5.txt +32 -0
- package/config/kb/prompt/rag/gpt-5.x.txt +32 -0
- package/config/kb/situatedContext.js +6 -0
- package/event/messageEvent.js +24 -0
- package/middleware/file-type.js +109 -36
- package/models/request.js +1 -0
- package/package.json +1 -1
- package/pubmodules/queue/reconnect.js +16 -0
- package/pubmodules/routing-queue/listenerQueued.js +22 -3
- package/pubmodules/scheduler/tasks/closeAgentUnresponsiveRequestTask.js +2 -1
- package/pubmodules/scheduler/tasks/closeBotUnresponsiveRequestTask.js +2 -1
- package/routes/filesp.js +4 -3
- package/routes/kb.js +348 -40
- package/routes/quotes.js +9 -2
- package/routes/request.js +174 -92
- package/routes/webhook.js +5 -0
- package/services/aiManager.js +93 -1
- package/services/aiService.js +33 -8
- package/services/fileGridFsService.js +1 -2
package/routes/request.js
CHANGED
|
@@ -318,6 +318,10 @@ router.patch('/:requestid', function (req, res) {
|
|
|
318
318
|
return res.status(404).send({ success: false, msg: 'Request not found' });
|
|
319
319
|
}
|
|
320
320
|
|
|
321
|
+
if (update.workingStatus !== undefined) {
|
|
322
|
+
requestEvent.emit('request.workingStatus.update', { request });
|
|
323
|
+
}
|
|
324
|
+
|
|
321
325
|
requestEvent.emit("request.update", request);
|
|
322
326
|
requestEvent.emit("request.update.comment", { comment: "PATCH", request: request }); //Deprecated
|
|
323
327
|
requestEvent.emit("request.updated", { comment: "PATCH", request: request, patch: update });
|
|
@@ -1376,6 +1380,10 @@ router.get('/', function (req, res, next) {
|
|
|
1376
1380
|
}
|
|
1377
1381
|
}
|
|
1378
1382
|
|
|
1383
|
+
if (req.query.workingStatus?.ne) {
|
|
1384
|
+
query.workingStatus = { $ne: req.query.workingStatus.ne };
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1379
1387
|
if (req.query.priority) {
|
|
1380
1388
|
query.priority = req.query.priority;
|
|
1381
1389
|
}
|
|
@@ -1421,10 +1429,31 @@ router.get('/', function (req, res, next) {
|
|
|
1421
1429
|
query["attributes.fully_abandoned"] = true
|
|
1422
1430
|
}
|
|
1423
1431
|
|
|
1432
|
+
if (req.query.rated && (req.query.rated === true || req.query.rated === 'true')) {
|
|
1433
|
+
query.rating = { $exists: true }
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1424
1436
|
if (req.query.draft && (req.query.draft === 'false' || req.query.draft === false)) {
|
|
1425
1437
|
query.draft = { $in: [false, null] }
|
|
1426
1438
|
}
|
|
1427
1439
|
|
|
1440
|
+
let inWStatus = req.query.workingStatus?.in?.split(',').map(s => s.trim()).filter(Boolean);
|
|
1441
|
+
let ninWStatus = req.query.workingStatus?.nin?.split(',').map(s => s.trim()).filter(Boolean);
|
|
1442
|
+
|
|
1443
|
+
if (ninWStatus && ninWStatus.length > 0) {
|
|
1444
|
+
if (ninWStatus.length === 1) {
|
|
1445
|
+
query.workingStatus = { $ne: ninWStatus[0] };
|
|
1446
|
+
} else {
|
|
1447
|
+
query.workingStatus = { $nin: ninWStatus };
|
|
1448
|
+
}
|
|
1449
|
+
} else if (inWStatus && inWStatus.length > 0) {
|
|
1450
|
+
if (inWStatus.length === 1) {
|
|
1451
|
+
query.workingStatus = inWStatus[0];
|
|
1452
|
+
} else {
|
|
1453
|
+
query.workingStatus = { $in: inWStatus };
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1456
|
+
|
|
1428
1457
|
var projection = undefined;
|
|
1429
1458
|
|
|
1430
1459
|
if (req.query.full_text) {
|
|
@@ -1872,57 +1901,67 @@ router.get('/csv', function (req, res, next) {
|
|
|
1872
1901
|
|
|
1873
1902
|
var limit = 100000; // Number of request per page
|
|
1874
1903
|
var page = 0;
|
|
1904
|
+
var skip = 0;
|
|
1905
|
+
let statusArray = [];
|
|
1906
|
+
var projectuser = req.projectuser;
|
|
1907
|
+
let filterRangeField = req.query.filterRangeField || 'createdAt';
|
|
1875
1908
|
|
|
1876
1909
|
if (req.query.page) {
|
|
1877
1910
|
page = req.query.page;
|
|
1878
1911
|
}
|
|
1879
1912
|
|
|
1880
|
-
|
|
1913
|
+
skip = page * limit;
|
|
1881
1914
|
winston.debug('REQUEST ROUTE - SKIP PAGE ', skip);
|
|
1882
1915
|
|
|
1883
|
-
|
|
1916
|
+
// Default query (same as GET /)
|
|
1917
|
+
var query = { "id_project": req.projectid, "status": { $lt: 1000, $nin: [50, 150] }, preflight: false };
|
|
1884
1918
|
|
|
1885
|
-
|
|
1919
|
+
if (req.user instanceof Subscription) {
|
|
1920
|
+
// All request
|
|
1921
|
+
} else if (projectuser && (projectuser.role == "owner" || projectuser.role == "admin")) {
|
|
1922
|
+
if (req.query.mine) {
|
|
1923
|
+
query["$or"] = [{ "snapshot.agents.id_user": req.user.id }, { "participants": req.user.id }];
|
|
1924
|
+
}
|
|
1925
|
+
} else {
|
|
1926
|
+
query["$or"] = [{ "snapshot.agents.id_user": req.user.id }, { "participants": req.user.id }];
|
|
1927
|
+
}
|
|
1886
1928
|
|
|
1887
1929
|
if (req.query.dept_id) {
|
|
1888
1930
|
query.department = req.query.dept_id;
|
|
1889
1931
|
winston.debug('REQUEST ROUTE - QUERY DEPT ID', query.department);
|
|
1890
1932
|
}
|
|
1891
1933
|
|
|
1934
|
+
if (req.query.requester_email) {
|
|
1935
|
+
query["snapshot.lead.email"] = req.query.requester_email;
|
|
1936
|
+
}
|
|
1937
|
+
|
|
1892
1938
|
if (req.query.full_text) {
|
|
1893
1939
|
winston.debug('req.query.fulltext', req.query.full_text);
|
|
1894
1940
|
query.$text = { "$search": req.query.full_text };
|
|
1895
1941
|
}
|
|
1896
1942
|
|
|
1897
|
-
if (req.query.
|
|
1943
|
+
if (req.query.phone) {
|
|
1944
|
+
var phoneDigits = req.query.phone.replace(/\D/g, '');
|
|
1945
|
+
if (phoneDigits.length > 0) {
|
|
1946
|
+
query["contact.phone"] = new RegExp(phoneDigits);
|
|
1947
|
+
}
|
|
1948
|
+
}
|
|
1949
|
+
|
|
1950
|
+
var history_search = false;
|
|
1898
1951
|
|
|
1952
|
+
// Multiple status management (same as GET /)
|
|
1953
|
+
if (req.query.status) {
|
|
1899
1954
|
if (req.query.status === 'all') {
|
|
1900
1955
|
delete query.status;
|
|
1901
1956
|
} else {
|
|
1902
|
-
|
|
1903
|
-
statusArray = statusArray.map(status => { return isNaN(status) ? null : status }).filter(status => status !== null)
|
|
1957
|
+
statusArray = req.query.status.split(',').map(Number);
|
|
1958
|
+
statusArray = statusArray.map(status => { return isNaN(status) ? null : status }).filter(status => status !== null);
|
|
1904
1959
|
if (statusArray.length > 0) {
|
|
1905
|
-
query.status = {
|
|
1906
|
-
$in: statusArray
|
|
1907
|
-
}
|
|
1960
|
+
query.status = { $in: statusArray };
|
|
1908
1961
|
} else {
|
|
1909
1962
|
delete query.status;
|
|
1910
1963
|
}
|
|
1911
1964
|
}
|
|
1912
|
-
|
|
1913
|
-
if (statusArray.length > 0) {
|
|
1914
|
-
query.status = {
|
|
1915
|
-
$in: statusArray
|
|
1916
|
-
}
|
|
1917
|
-
}
|
|
1918
|
-
|
|
1919
|
-
}
|
|
1920
|
-
|
|
1921
|
-
if (req.query.preflight) {
|
|
1922
|
-
let preflight = (req.query.preflight === 'false');
|
|
1923
|
-
if (preflight) {
|
|
1924
|
-
query.preflight = false;
|
|
1925
|
-
}
|
|
1926
1965
|
}
|
|
1927
1966
|
|
|
1928
1967
|
if (req.query.lead) {
|
|
@@ -1942,49 +1981,96 @@ router.get('/csv', function (req, res, next) {
|
|
|
1942
1981
|
query.hasBot = req.query.hasbot;
|
|
1943
1982
|
}
|
|
1944
1983
|
|
|
1945
|
-
|
|
1946
|
-
|
|
1947
|
-
|
|
1948
|
-
|
|
1949
|
-
|
|
1984
|
+
if (req.query.tags) {
|
|
1985
|
+
query["tags.tag"] = req.query.tags;
|
|
1986
|
+
}
|
|
1987
|
+
|
|
1988
|
+
if (req.query.location) {
|
|
1989
|
+
query.location = req.query.location;
|
|
1990
|
+
}
|
|
1991
|
+
|
|
1992
|
+
if (req.query.ticket_id) {
|
|
1993
|
+
query.ticket_id = req.query.ticket_id;
|
|
1994
|
+
}
|
|
1995
|
+
|
|
1996
|
+
if (req.query.preflight && (req.query.preflight === 'true' || req.query.preflight === true)) {
|
|
1997
|
+
delete query.preflight;
|
|
1998
|
+
}
|
|
1999
|
+
|
|
2000
|
+
let timezone = req.query.timezone || 'Europe/Rome';
|
|
2001
|
+
let queryDateRange = false;
|
|
2002
|
+
let queryStartDate;
|
|
2003
|
+
let queryEndDate;
|
|
2004
|
+
|
|
2005
|
+
if (history_search === true && req.project && req.project.profile && ((req.project.profile.type === 'free' && req.project.trialExpired === true) || (req.project.profile.type === 'payment' && req.project.isActiveSubscription === false))) {
|
|
2006
|
+
queryDateRange = true;
|
|
2007
|
+
queryStartDate = moment().subtract(14, "days").format("YYYY/MM/DD");
|
|
2008
|
+
queryEndDate = null;
|
|
2009
|
+
}
|
|
1950
2010
|
|
|
1951
|
-
|
|
1952
|
-
|
|
1953
|
-
|
|
1954
|
-
|
|
1955
|
-
|
|
2011
|
+
if (req.query.start_date || req.query.end_date) {
|
|
2012
|
+
queryDateRange = true;
|
|
2013
|
+
queryStartDate = req.query.start_date;
|
|
2014
|
+
queryEndDate = req.query.end_date;
|
|
2015
|
+
} else if (req.query.start_date_time || req.query.end_date_time) {
|
|
2016
|
+
queryDateRange = true;
|
|
2017
|
+
queryStartDate = req.query.start_date_time;
|
|
2018
|
+
queryEndDate = req.query.end_date_time;
|
|
2019
|
+
}
|
|
1956
2020
|
|
|
2021
|
+
if (queryDateRange) {
|
|
2022
|
+
try {
|
|
2023
|
+
let rangeQuery = datesUtil.createDateRangeQuery(queryStartDate, queryEndDate, timezone, filterRangeField);
|
|
2024
|
+
Object.assign(query, rangeQuery);
|
|
2025
|
+
} catch (error) {
|
|
2026
|
+
winston.error('Error creating date range query: ', error);
|
|
2027
|
+
return res.status(500).send({ success: false, error: error?.message });
|
|
2028
|
+
}
|
|
2029
|
+
}
|
|
1957
2030
|
|
|
1958
|
-
|
|
1959
|
-
|
|
1960
|
-
|
|
1961
|
-
var endDate = moment(req.query.end_date, 'DD/MM/YYYY').format('YYYY-MM-DD');
|
|
2031
|
+
if (req.query.snap_department_routing) {
|
|
2032
|
+
query["snapshot.department.routing"] = req.query.snap_department_routing;
|
|
2033
|
+
}
|
|
1962
2034
|
|
|
1963
|
-
|
|
1964
|
-
|
|
2035
|
+
if (req.query.snap_department_default) {
|
|
2036
|
+
query["snapshot.department.default"] = req.query.snap_department_default;
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
if (req.query.snap_department_id_bot) {
|
|
2040
|
+
query["snapshot.department.id_bot"] = req.query.snap_department_id_bot;
|
|
2041
|
+
}
|
|
1965
2042
|
|
|
1966
|
-
|
|
1967
|
-
|
|
1968
|
-
|
|
1969
|
-
var endDate_plusOneDay = newdate.setDate(newdate.getDate() + 1);
|
|
1970
|
-
winston.debug('REQUEST ROUTE - REQ QUERY FORMATTED END DATE + 1 DAY ', endDate_plusOneDay);
|
|
1971
|
-
// var endDate_plusOneDay = moment('2018-09-03').add(1, 'd')
|
|
1972
|
-
// var endDate_plusOneDay = endDate.add(1).day();
|
|
1973
|
-
// var toDate = new Date(Date.parse(endDate_plusOneDay)).toISOString()
|
|
2043
|
+
if (req.query.snap_department_id_bot_exists) {
|
|
2044
|
+
query["snapshot.department.id_bot"] = { "$exists": req.query.snap_department_id_bot_exists };
|
|
2045
|
+
}
|
|
1974
2046
|
|
|
1975
|
-
|
|
1976
|
-
|
|
2047
|
+
if (req.query.snap_lead_lead_id) {
|
|
2048
|
+
query["snapshot.lead.lead_id"] = req.query.snap_lead_lead_id;
|
|
2049
|
+
}
|
|
1977
2050
|
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
2051
|
+
if (req.query.snap_lead_email) {
|
|
2052
|
+
query["snapshot.lead.email"] = req.query.snap_lead_email;
|
|
2053
|
+
}
|
|
1981
2054
|
|
|
1982
|
-
|
|
1983
|
-
|
|
2055
|
+
if (req.query.smartAssignment) {
|
|
2056
|
+
query.smartAssignment = req.query.smartAssignment;
|
|
1984
2057
|
}
|
|
1985
|
-
winston.debug("csv query", query);
|
|
1986
2058
|
|
|
1987
|
-
|
|
2059
|
+
if (req.query.channel) {
|
|
2060
|
+
if (req.query.channel === "offline") {
|
|
2061
|
+
query["channel.name"] = { "$in": ["email", "form"] };
|
|
2062
|
+
} else if (req.query.channel === "online") {
|
|
2063
|
+
query["channel.name"] = { "$nin": ["email", "form"] };
|
|
2064
|
+
} else {
|
|
2065
|
+
query["channel.name"] = req.query.channel;
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
|
|
2069
|
+
if (req.query.priority) {
|
|
2070
|
+
query.priority = req.query.priority;
|
|
2071
|
+
}
|
|
2072
|
+
|
|
2073
|
+
var direction = -1; // same default as GET /
|
|
1988
2074
|
if (req.query.direction) {
|
|
1989
2075
|
direction = req.query.direction;
|
|
1990
2076
|
}
|
|
@@ -1998,20 +2084,9 @@ router.get('/csv', function (req, res, next) {
|
|
|
1998
2084
|
|
|
1999
2085
|
var sortQuery = {};
|
|
2000
2086
|
sortQuery[sortField] = direction;
|
|
2001
|
-
|
|
2002
2087
|
winston.debug("sort query", sortQuery);
|
|
2003
2088
|
|
|
2004
|
-
|
|
2005
|
-
if (req.query.channel === "offline") {
|
|
2006
|
-
query["channel.name"] = { "$in": ["email", "form"] }
|
|
2007
|
-
} else if (req.query.channel === "online") {
|
|
2008
|
-
query["channel.name"] = { "$nin": ["email", "form"] }
|
|
2009
|
-
} else {
|
|
2010
|
-
query["channel.name"] = req.query.channel
|
|
2011
|
-
}
|
|
2012
|
-
}
|
|
2013
|
-
|
|
2014
|
-
// VOICE FILTERS - Start
|
|
2089
|
+
// VOICE FILTERS
|
|
2015
2090
|
if (req.query.caller) {
|
|
2016
2091
|
query["attributes.caller_phone"] = req.query.caller;
|
|
2017
2092
|
}
|
|
@@ -2021,45 +2096,52 @@ router.get('/csv', function (req, res, next) {
|
|
|
2021
2096
|
if (req.query.call_id) {
|
|
2022
2097
|
query["attributes.call_id"] = req.query.call_id;
|
|
2023
2098
|
}
|
|
2024
|
-
// VOICE FILTERS - End
|
|
2025
|
-
|
|
2026
|
-
// TODO ORDER BY SCORE
|
|
2027
|
-
// return Faq.find(query, {score: { $meta: "textScore" } })
|
|
2028
|
-
// .sort( { score: { $meta: "textScore" } } ) //https://docs.mongodb.com/manual/reference/operator/query/text/#sort-by-text-search-score
|
|
2029
|
-
|
|
2030
|
-
// aggiungi filtro per data marco
|
|
2031
2099
|
|
|
2032
2100
|
if (req.query.duration && req.query.duration_op) {
|
|
2033
2101
|
let duration = Number(req.query.duration) * 60 * 1000;
|
|
2034
2102
|
if (req.query.duration_op === 'gt') {
|
|
2035
|
-
query.duration = { $gte: duration }
|
|
2103
|
+
query.duration = { $gte: duration };
|
|
2036
2104
|
} else if (req.query.duration_op === 'lt') {
|
|
2037
|
-
query.duration = { $lte: duration }
|
|
2105
|
+
query.duration = { $lte: duration };
|
|
2038
2106
|
} else {
|
|
2039
|
-
winston.verbose("Duration operator can be 'gt' or 'lt'. Skip duration_op " + req.query.duration_op)
|
|
2107
|
+
winston.verbose("Duration operator can be 'gt' or 'lt'. Skip duration_op " + req.query.duration_op);
|
|
2040
2108
|
}
|
|
2041
2109
|
}
|
|
2042
2110
|
|
|
2111
|
+
if (req.query.abandonded && (req.query.abandoned === true || req.query.abandoned === 'true')) {
|
|
2112
|
+
query["attributes.fully_abandoned"] = true;
|
|
2113
|
+
}
|
|
2114
|
+
|
|
2115
|
+
if (req.query.rated && (req.query.rated === true || req.query.rated === 'true')) {
|
|
2116
|
+
query.rating = { $exists: true };
|
|
2117
|
+
}
|
|
2118
|
+
|
|
2043
2119
|
if (req.query.draft && (req.query.draft === 'false' || req.query.draft === false)) {
|
|
2044
|
-
query.draft = { $in: [false, null] }
|
|
2120
|
+
query.draft = { $in: [false, null] };
|
|
2045
2121
|
}
|
|
2046
2122
|
|
|
2047
|
-
|
|
2048
|
-
|
|
2123
|
+
var csvProjection = '-transcript -status -__v';
|
|
2124
|
+
if (req.query.full_text && req.query.no_textscore != "true" && req.query.no_textscore != true) {
|
|
2125
|
+
winston.verbose('fulltext projection on');
|
|
2126
|
+
csvProjection = { transcript: 0, status: 0, __v: 0, score: { $meta: "textScore" } };
|
|
2127
|
+
}
|
|
2128
|
+
|
|
2129
|
+
winston.debug("csv query", query);
|
|
2130
|
+
winston.debug('REQUEST ROUTE - REQUEST FIND ', query);
|
|
2131
|
+
|
|
2132
|
+
var q = Request.find(query, csvProjection).
|
|
2049
2133
|
skip(skip).limit(limit).
|
|
2050
|
-
//populate('department', {'_id':-1, 'name':1}).
|
|
2051
2134
|
populate('department').
|
|
2052
2135
|
populate('lead').
|
|
2053
|
-
|
|
2054
|
-
|
|
2055
|
-
|
|
2056
|
-
|
|
2057
|
-
|
|
2058
|
-
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
|
|
2062
|
-
exec(function (err, requests) {
|
|
2136
|
+
lean();
|
|
2137
|
+
|
|
2138
|
+
if (req.query.full_text && req.query.no_textscore != "true" && req.query.no_textscore != true) {
|
|
2139
|
+
q.sort({ score: { $meta: "textScore" } });
|
|
2140
|
+
} else {
|
|
2141
|
+
q.sort(sortQuery);
|
|
2142
|
+
}
|
|
2143
|
+
|
|
2144
|
+
return q.exec(function (err, requests) {
|
|
2063
2145
|
if (err) {
|
|
2064
2146
|
winston.error('REQUEST ROUTE - REQUEST FIND ERR ', err)
|
|
2065
2147
|
return res.status(500).send({ success: false, msg: 'Error getting csv requests.', err: err });
|
package/routes/webhook.js
CHANGED
|
@@ -193,6 +193,11 @@ router.post('/kb/reindex', async (req, res) => {
|
|
|
193
193
|
embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
|
|
194
194
|
json.embedding = embedding;
|
|
195
195
|
|
|
196
|
+
const situated_context = aiManager.normalizeSituatedContext();
|
|
197
|
+
if (situated_context) {
|
|
198
|
+
json.situated_context = situated_context;
|
|
199
|
+
}
|
|
200
|
+
|
|
196
201
|
let resources = [];
|
|
197
202
|
resources.push(json);
|
|
198
203
|
|
package/services/aiManager.js
CHANGED
|
@@ -5,6 +5,7 @@ const { Scheduler } = require("./Scheduler");
|
|
|
5
5
|
const { default: Sitemapper } = require('sitemapper');
|
|
6
6
|
const winston = require('../config/winston');
|
|
7
7
|
const configGlobal = require('../config/global');
|
|
8
|
+
const _ = require('lodash');
|
|
8
9
|
const JobManager = require('../utils/jobs-worker-queue-manager/JobManagerV2');
|
|
9
10
|
|
|
10
11
|
// Constants
|
|
@@ -19,6 +20,7 @@ const default_engine = require('../config/kb/engine');
|
|
|
19
20
|
const default_engine_hybrid = require('../config/kb/engine.hybrid');
|
|
20
21
|
const default_embedding = require('../config/kb/embedding');
|
|
21
22
|
const integrationService = require('./integrationService');
|
|
23
|
+
const situatedContext = require('../config/kb/situatedContext');
|
|
22
24
|
|
|
23
25
|
// Job managers
|
|
24
26
|
let jobManager = new JobManager(AMQP_MANAGER_URL, {
|
|
@@ -92,11 +94,22 @@ class AiManager {
|
|
|
92
94
|
let engine = namespace.engine || default_engine;
|
|
93
95
|
let embedding = namespace.embedding || default_embedding;
|
|
94
96
|
embedding.api_key = process.env.EMBEDDING_API_KEY || process.env.GPTKEY;
|
|
97
|
+
|
|
98
|
+
let situated_context = this.normalizeSituatedContext();
|
|
99
|
+
|
|
95
100
|
let webhook = apiUrl + '/webhook/kb/status?token=' + KB_WEBHOOK_TOKEN;
|
|
96
101
|
|
|
97
102
|
let resources = result.map(({ name, status, __v, createdAt, updatedAt, id_project, ...keepAttrs }) => keepAttrs)
|
|
98
103
|
resources = resources.map(({ _id, scrape_options, ...rest }) => {
|
|
99
|
-
return {
|
|
104
|
+
return {
|
|
105
|
+
id: _id,
|
|
106
|
+
webhook: webhook,
|
|
107
|
+
parameters_scrape_type_4: scrape_options,
|
|
108
|
+
embedding: embedding,
|
|
109
|
+
engine: engine,
|
|
110
|
+
hybrid: hybrid,
|
|
111
|
+
...(situated_context && { situated_context }),
|
|
112
|
+
...rest}
|
|
100
113
|
});
|
|
101
114
|
|
|
102
115
|
winston.verbose("resources to be sent to worker: ", resources);
|
|
@@ -119,6 +132,8 @@ class AiManager {
|
|
|
119
132
|
async scheduleSitemap(namespace, sitemap_content, options) {
|
|
120
133
|
return new Promise((resolve, reject) => {
|
|
121
134
|
|
|
135
|
+
const situated_context = this.normalizeSituatedContext();
|
|
136
|
+
|
|
122
137
|
let kb = {
|
|
123
138
|
id: sitemap_content._id,
|
|
124
139
|
source: sitemap_content.source,
|
|
@@ -129,6 +144,7 @@ class AiManager {
|
|
|
129
144
|
engine: namespace.engine,
|
|
130
145
|
embedding: namespace.embedding,
|
|
131
146
|
hybrid: namespace.hybrid,
|
|
147
|
+
...(situated_context && { situated_context }),
|
|
132
148
|
}
|
|
133
149
|
|
|
134
150
|
if (process.env.NODE_ENV === 'test') {
|
|
@@ -142,6 +158,73 @@ class AiManager {
|
|
|
142
158
|
})
|
|
143
159
|
}
|
|
144
160
|
|
|
161
|
+
async updateSitemap(id_project, namespace, old_sitemap, new_sitemap) {
|
|
162
|
+
|
|
163
|
+
let fieldsToCheck = ['scrape_type', 'scrape_options', 'refresh_rate', 'tags'];
|
|
164
|
+
let { stop } = this.shouldStop(old_sitemap, new_sitemap, fieldsToCheck);
|
|
165
|
+
|
|
166
|
+
let updated_sitemap;
|
|
167
|
+
try {
|
|
168
|
+
updated_sitemap = await KB.findOneAndUpdate({ id_project, namespace: namespace.id, _id: old_sitemap._id }, new_sitemap, { new: true });
|
|
169
|
+
} catch (err) {
|
|
170
|
+
winston.error("Error updating sitemap: ", err);
|
|
171
|
+
throw err;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (stop) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// Find all url contents with sitemap_origin_id
|
|
179
|
+
let urlContents = await KB.find({ id_project, namespace: namespace.id, sitemap_origin_id: old_sitemap._id }).lean().exec();
|
|
180
|
+
if (urlContents.length === 0) {
|
|
181
|
+
winston.error("No url contents found with sitemap_origin_id: ", old_sitemap._id);
|
|
182
|
+
throw new Error("No url contents found with sitemap_origin_id: " + old_sitemap._id);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Remove all url contents found with sitemap_origin_id
|
|
186
|
+
try {
|
|
187
|
+
await this.removeMultipleContents(namespace, urlContents);
|
|
188
|
+
} catch (err) {
|
|
189
|
+
winston.error("Error removing multiple contents: ", err);
|
|
190
|
+
throw err;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// Recreate all url contents with sitemap_origin_id
|
|
194
|
+
let result;
|
|
195
|
+
try {
|
|
196
|
+
result = await this.addMultipleUrls(namespace, urlContents.map(urlContent => urlContent.source), {
|
|
197
|
+
sitemap_origin_id: updated_sitemap._id,
|
|
198
|
+
sitemap_origin: updated_sitemap.source,
|
|
199
|
+
scrape_type: updated_sitemap.scrape_type,
|
|
200
|
+
scrape_options: updated_sitemap.scrape_options,
|
|
201
|
+
refresh_rate: updated_sitemap.refresh_rate,
|
|
202
|
+
tags: updated_sitemap.tags,
|
|
203
|
+
});
|
|
204
|
+
} catch (err) {
|
|
205
|
+
winston.error("Error recreating multiple contents: ", err);
|
|
206
|
+
throw err;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return result;
|
|
210
|
+
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
shouldStop(oldObj, newObj, fieldsToCheck) {
|
|
216
|
+
for (const field of fieldsToCheck) {
|
|
217
|
+
const oldValue = _.get(oldObj, field);
|
|
218
|
+
const newValue = _.get(newObj, field);
|
|
219
|
+
|
|
220
|
+
if (!_.isEqual(oldValue, newValue)) {
|
|
221
|
+
return { stop: false };
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
return { stop: true };
|
|
226
|
+
}
|
|
227
|
+
|
|
145
228
|
async checkNamespace(id_project, namespace_id) {
|
|
146
229
|
return new Promise( async (resolve, reject) => {
|
|
147
230
|
|
|
@@ -484,6 +567,15 @@ class AiManager {
|
|
|
484
567
|
})
|
|
485
568
|
}
|
|
486
569
|
|
|
570
|
+
normalizeSituatedContext() {
|
|
571
|
+
return situatedContext.enable
|
|
572
|
+
? {
|
|
573
|
+
...situatedContext,
|
|
574
|
+
api_key: process.env.SITUATED_CONTEXT_API_KEY || process.env.GPTKEY
|
|
575
|
+
}
|
|
576
|
+
: undefined;
|
|
577
|
+
}
|
|
578
|
+
|
|
487
579
|
}
|
|
488
580
|
|
|
489
581
|
const aiManager = new AiManager();
|
package/services/aiService.js
CHANGED
|
@@ -206,16 +206,18 @@ class AiService {
|
|
|
206
206
|
}
|
|
207
207
|
winston.debug("[OPENAI SERVICE] kb endpoint: " + base_url);
|
|
208
208
|
|
|
209
|
+
const config = {
|
|
210
|
+
url: base_url + "/qa",
|
|
211
|
+
headers: {
|
|
212
|
+
'Content-Type': 'application/json'
|
|
213
|
+
},
|
|
214
|
+
data: data,
|
|
215
|
+
method: 'POST'
|
|
216
|
+
};
|
|
217
|
+
|
|
209
218
|
return new Promise((resolve, reject) => {
|
|
210
219
|
|
|
211
|
-
axios({
|
|
212
|
-
url: base_url + "/qa",
|
|
213
|
-
headers: {
|
|
214
|
-
'Content-Type': 'application/json'
|
|
215
|
-
},
|
|
216
|
-
data: data,
|
|
217
|
-
method: 'POST'
|
|
218
|
-
}).then((resbody) => {
|
|
220
|
+
axios(config).then((resbody) => {
|
|
219
221
|
resolve(resbody);
|
|
220
222
|
}).catch((err) => {
|
|
221
223
|
reject(err);
|
|
@@ -224,6 +226,29 @@ class AiService {
|
|
|
224
226
|
})
|
|
225
227
|
}
|
|
226
228
|
|
|
229
|
+
/**
|
|
230
|
+
* Stream /qa from KB service. Uses Axios with responseType: 'stream'.
|
|
231
|
+
* Returns the raw Axios response (resp.data is the Node.js Readable stream).
|
|
232
|
+
*/
|
|
233
|
+
askStream(data) {
|
|
234
|
+
winston.debug("askStream data: ", data);
|
|
235
|
+
let base_url = kb_endpoint_qa;
|
|
236
|
+
if (data.hybrid || data.search_type === 'hybrid') {
|
|
237
|
+
base_url = kb_endpoint_qa_gpu;
|
|
238
|
+
}
|
|
239
|
+
winston.debug("[OPENAI SERVICE] kb stream endpoint: " + base_url);
|
|
240
|
+
|
|
241
|
+
return axios({
|
|
242
|
+
url: base_url + "/qa",
|
|
243
|
+
headers: {
|
|
244
|
+
'Content-Type': 'application/json'
|
|
245
|
+
},
|
|
246
|
+
data: data,
|
|
247
|
+
method: 'POST',
|
|
248
|
+
responseType: 'stream'
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
|
|
227
252
|
getContentChunks(namespace_id, content_id, engine, hybrid) {
|
|
228
253
|
let base_url = kb_endpoint_train;
|
|
229
254
|
winston.debug("[OPENAI SERVICE] kb endpoint: " + base_url);
|
|
@@ -177,10 +177,9 @@ class FileGridFsService extends FileService {
|
|
|
177
177
|
return reject(e);
|
|
178
178
|
})
|
|
179
179
|
stream.on('data', (data) => {
|
|
180
|
-
bufs.push(data);
|
|
180
|
+
bufs.push(Buffer.isBuffer(data) ? data : Buffer.from(data));
|
|
181
181
|
});
|
|
182
182
|
stream.on('end', () => {
|
|
183
|
-
|
|
184
183
|
var buffer = Buffer.concat(bufs);
|
|
185
184
|
return resolve(buffer);
|
|
186
185
|
});
|