@resolveio/server-lib 20.14.28 → 20.14.30
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/managers/subscription.manager.d.ts +0 -52
- package/managers/subscription.manager.js +30 -510
- package/managers/subscription.manager.js.map +1 -1
- package/methods/ai-terminal.d.ts +20 -0
- package/methods/ai-terminal.js +320 -18
- package/methods/ai-terminal.js.map +1 -1
- package/methods.ts +3 -0
- package/package.json +1 -1
package/methods/ai-terminal.d.ts
CHANGED
|
@@ -18,5 +18,25 @@ export type AiAssistantMongoReadInput = {
|
|
|
18
18
|
readonly?: boolean;
|
|
19
19
|
};
|
|
20
20
|
};
|
|
21
|
+
export type AiAssistantMongoAggregateInput = {
|
|
22
|
+
database?: string;
|
|
23
|
+
collection?: string;
|
|
24
|
+
query?: Record<string, any>;
|
|
25
|
+
pipeline?: Array<Record<string, any>>;
|
|
26
|
+
options?: {
|
|
27
|
+
allowDiskUse?: boolean;
|
|
28
|
+
maxTimeMS?: number;
|
|
29
|
+
limit?: number;
|
|
30
|
+
};
|
|
31
|
+
permissionView?: string;
|
|
32
|
+
id_client?: string;
|
|
33
|
+
mongo?: {
|
|
34
|
+
database?: string;
|
|
35
|
+
databases?: string[];
|
|
36
|
+
access?: string;
|
|
37
|
+
readonly?: boolean;
|
|
38
|
+
};
|
|
39
|
+
};
|
|
21
40
|
export declare function loadAiTerminalMethods(methodManager: any): void;
|
|
22
41
|
export declare function executeAiAssistantMongoRead(payload: AiAssistantMongoReadInput, context: any): Promise<any>;
|
|
42
|
+
export declare function executeAiAssistantMongoAggregate(payload: AiAssistantMongoAggregateInput, context: any): Promise<any>;
|
package/methods/ai-terminal.js
CHANGED
|
@@ -14,6 +14,17 @@ var __extends = (this && this.__extends) || (function () {
|
|
|
14
14
|
d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
|
|
15
15
|
};
|
|
16
16
|
})();
|
|
17
|
+
var __assign = (this && this.__assign) || function () {
|
|
18
|
+
__assign = Object.assign || function(t) {
|
|
19
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
20
|
+
s = arguments[i];
|
|
21
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
22
|
+
t[p] = s[p];
|
|
23
|
+
}
|
|
24
|
+
return t;
|
|
25
|
+
};
|
|
26
|
+
return __assign.apply(this, arguments);
|
|
27
|
+
};
|
|
17
28
|
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
18
29
|
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
19
30
|
return new (P || (P = Promise))(function (resolve, reject) {
|
|
@@ -50,17 +61,6 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
|
|
|
50
61
|
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
51
62
|
}
|
|
52
63
|
};
|
|
53
|
-
var __values = (this && this.__values) || function(o) {
|
|
54
|
-
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
55
|
-
if (m) return m.call(o);
|
|
56
|
-
if (o && typeof o.length === "number") return {
|
|
57
|
-
next: function () {
|
|
58
|
-
if (o && i >= o.length) o = void 0;
|
|
59
|
-
return { value: o && o[i++], done: !o };
|
|
60
|
-
}
|
|
61
|
-
};
|
|
62
|
-
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
63
|
-
};
|
|
64
64
|
var __read = (this && this.__read) || function (o, n) {
|
|
65
65
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
66
66
|
if (!m) return o;
|
|
@@ -77,9 +77,30 @@ var __read = (this && this.__read) || function (o, n) {
|
|
|
77
77
|
}
|
|
78
78
|
return ar;
|
|
79
79
|
};
|
|
80
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
81
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
82
|
+
if (ar || !(i in from)) {
|
|
83
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
84
|
+
ar[i] = from[i];
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
88
|
+
};
|
|
89
|
+
var __values = (this && this.__values) || function(o) {
|
|
90
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
91
|
+
if (m) return m.call(o);
|
|
92
|
+
if (o && typeof o.length === "number") return {
|
|
93
|
+
next: function () {
|
|
94
|
+
if (o && i >= o.length) o = void 0;
|
|
95
|
+
return { value: o && o[i++], done: !o };
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
99
|
+
};
|
|
80
100
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
81
101
|
exports.loadAiTerminalMethods = loadAiTerminalMethods;
|
|
82
102
|
exports.executeAiAssistantMongoRead = executeAiAssistantMongoRead;
|
|
103
|
+
exports.executeAiAssistantMongoAggregate = executeAiAssistantMongoAggregate;
|
|
83
104
|
var fs_1 = require("fs");
|
|
84
105
|
var events_1 = require("events");
|
|
85
106
|
var os = require("os");
|
|
@@ -104,6 +125,10 @@ var DEFAULT_CODEX_MODEL = 'gpt-5.2-codex';
|
|
|
104
125
|
var DEFAULT_CODEX_TIMEOUT_MS = 180000;
|
|
105
126
|
var AI_ASSISTANT_MONGO_DEFAULT_LIMIT = 20;
|
|
106
127
|
var AI_ASSISTANT_MONGO_MAX_LIMIT = 200;
|
|
128
|
+
var AI_ASSISTANT_DATE_FALLBACKS = {
|
|
129
|
+
date_created: 'createdAt',
|
|
130
|
+
createdAt: 'date_created'
|
|
131
|
+
};
|
|
107
132
|
var AI_ASSISTANT_BLOCKED_COLLECTIONS = new Set([
|
|
108
133
|
'user-groups',
|
|
109
134
|
'logged-in-users',
|
|
@@ -157,17 +182,22 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
157
182
|
'- If the user explicitly asks to create/open/file a support ticket, end your response with a single line exactly in this format:',
|
|
158
183
|
'- SUPPORT_TICKET_CREATE: <one-line summary>',
|
|
159
184
|
'- Only include that line when the user clearly wants a ticket created. Do not claim a ticket is created unless you include that line.',
|
|
185
|
+
'- Do not end responses with tentative phrasing like "I could" or "I’m going to." Complete the request or state what is required to proceed.',
|
|
186
|
+
'- Use the codebase context to choose correct collections/fields/workflows and use MONGO_READ/MONGO_AGG to answer with real data when needed.',
|
|
160
187
|
'- For direct questions, answer first. Ask a single follow-up only if required to run a query or resolve missing details.',
|
|
161
188
|
'- If you need database data to answer, end your response with a single line exactly in this format:',
|
|
162
189
|
'- MONGO_READ: {"collection":"<name>","query":{...},"options":{"projection":{...},"sort":{...},"limit":20},"permissionView":"</route>"}',
|
|
190
|
+
'- If you need grouped/aggregated data (totals by user, rankings, trends), end your response with a single line exactly in this format:',
|
|
191
|
+
'- MONGO_AGG: {"collection":"<name>","pipeline":[...],"options":{"allowDiskUse":true,"limit":20},"permissionView":"</route>"}',
|
|
163
192
|
'- For invoice data, set permissionView to an invoice route (ex: /invoice/list or /report/invoice).',
|
|
164
193
|
'- Keep queries minimal, read-only, and avoid user/credential data unless the user is a super admin.',
|
|
165
194
|
'- Assume you are not a super admin unless explicitly told otherwise.',
|
|
166
195
|
'- Only request data when the user has permission for that module; invoice data requires invoice view access.',
|
|
167
196
|
'- If the user lacks permission, answer without data and explain how to view it in the app or request access.',
|
|
168
|
-
'- For counts
|
|
169
|
-
'- Before issuing MONGO_READ, verify the collection name and key fields by checking collection/model definitions in the current app (look for "collectionName:" and date fields like date_created/date_completed/createdAt). Do not invent collection names.',
|
|
170
|
-
'-
|
|
197
|
+
'- For simple counts or time-range totals, use MONGO_READ (includeTotal). For breakdowns, rankings, or sums grouped by a field, use MONGO_AGG.',
|
|
198
|
+
'- Before issuing MONGO_READ or MONGO_AGG, verify the collection name and key fields by checking collection/model definitions in the current app (look for "collectionName:" and date fields like date_created/date_completed/createdAt). Do not invent collection names.',
|
|
199
|
+
'- For creation-date questions when both date_created and createdAt exist, match both with $or so results are not missed.',
|
|
200
|
+
'- Use MONGO_READ/MONGO_AGG only to produce summaries/snapshots/health checks (not raw dumps) when permitted.',
|
|
171
201
|
'- When referencing data, summarize it in bullets and avoid raw JSON or dumps.',
|
|
172
202
|
'- Keep responses concise and use low reasoning effort.'
|
|
173
203
|
].join('\n');
|
|
@@ -198,7 +228,7 @@ function loadAiTerminalMethods(methodManager) {
|
|
|
198
228
|
case 0:
|
|
199
229
|
now = new Date();
|
|
200
230
|
doc = {
|
|
201
|
-
id_client:
|
|
231
|
+
id_client: resolveClientIdFromConfig(payload.id_client),
|
|
202
232
|
id_app: normalizeOptionalString(payload.id_app),
|
|
203
233
|
title: normalizeOptionalString(payload.title) || 'New Conversation',
|
|
204
234
|
mode: normalizeConversationMode(payload.mode),
|
|
@@ -452,6 +482,24 @@ function loadAiTerminalMethods(methodManager) {
|
|
|
452
482
|
});
|
|
453
483
|
}
|
|
454
484
|
},
|
|
485
|
+
aiAssistantMongoAggregate: {
|
|
486
|
+
check: new simpl_schema_1.default({
|
|
487
|
+
payload: {
|
|
488
|
+
type: Object,
|
|
489
|
+
blackbox: true
|
|
490
|
+
}
|
|
491
|
+
}),
|
|
492
|
+
function: function (payload) {
|
|
493
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
494
|
+
return __generator(this, function (_a) {
|
|
495
|
+
switch (_a.label) {
|
|
496
|
+
case 0: return [4 /*yield*/, executeAiAssistantMongoAggregate(payload, this)];
|
|
497
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
498
|
+
}
|
|
499
|
+
});
|
|
500
|
+
});
|
|
501
|
+
}
|
|
502
|
+
},
|
|
455
503
|
aiCoderTerminalDeployTest: {
|
|
456
504
|
check: new simpl_schema_1.default({
|
|
457
505
|
id_conversation: {
|
|
@@ -655,7 +703,7 @@ function executeAiFormPatch(payload, context) {
|
|
|
655
703
|
case 1:
|
|
656
704
|
response = _b.sent();
|
|
657
705
|
usage = response.usage || estimateUsage(messages, response.content, response.model || openaiSettings.model);
|
|
658
|
-
idClient =
|
|
706
|
+
idClient = resolveClientIdFromConfig(input.id_client);
|
|
659
707
|
if (!idClient) return [3 /*break*/, 3];
|
|
660
708
|
return [4 /*yield*/, (0, openai_usage_ledger_manager_1.recordOpenAIUsage)({
|
|
661
709
|
id_client: idClient,
|
|
@@ -903,6 +951,89 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
903
951
|
});
|
|
904
952
|
});
|
|
905
953
|
}
|
|
954
|
+
function executeAiAssistantMongoAggregate(payload, context) {
|
|
955
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
956
|
+
var input, collection, _a, user, isSuperAdmin, customerId, dbName, db, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, documents, fallback, fallbackPipeline, fallbackDocs, sanitizedDocuments;
|
|
957
|
+
var _c;
|
|
958
|
+
return __generator(this, function (_d) {
|
|
959
|
+
switch (_d.label) {
|
|
960
|
+
case 0:
|
|
961
|
+
input = payload || {};
|
|
962
|
+
collection = normalizeOptionalString(input.collection);
|
|
963
|
+
if (!collection) {
|
|
964
|
+
throw new Error('AI assistant mongo aggregate: Collection is required.');
|
|
965
|
+
}
|
|
966
|
+
return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
|
|
967
|
+
case 1:
|
|
968
|
+
_a = _d.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
|
|
969
|
+
if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
|
|
970
|
+
throw new Error('AI assistant mongo aggregate: Access denied.');
|
|
971
|
+
}
|
|
972
|
+
customerId = normalizeOptionalString((_c = user === null || user === void 0 ? void 0 : user.other) === null || _c === void 0 ? void 0 : _c.id_customer);
|
|
973
|
+
dbName = resolveAssistantDatabaseName(input.database, input.mongo);
|
|
974
|
+
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
975
|
+
baseQuery = normalizeMongoQuery(input.query);
|
|
976
|
+
if (!isSuperAdmin && (collection === 'users' || collection === 'user-versions')) {
|
|
977
|
+
userId = normalizeOptionalString(user === null || user === void 0 ? void 0 : user._id);
|
|
978
|
+
if (!userId) {
|
|
979
|
+
throw new Error('AI assistant mongo aggregate: Access denied.');
|
|
980
|
+
}
|
|
981
|
+
baseQuery = {
|
|
982
|
+
$and: [baseQuery, { _id: userId }]
|
|
983
|
+
};
|
|
984
|
+
}
|
|
985
|
+
normalizedClient = normalizeOptionalString(input.id_client);
|
|
986
|
+
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 3];
|
|
987
|
+
return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
|
|
988
|
+
case 2:
|
|
989
|
+
_b = _d.sent();
|
|
990
|
+
return [3 /*break*/, 4];
|
|
991
|
+
case 3:
|
|
992
|
+
_b = false;
|
|
993
|
+
_d.label = 4;
|
|
994
|
+
case 4:
|
|
995
|
+
shouldScopeByClient = _b;
|
|
996
|
+
clientScopedQuery = shouldScopeByClient
|
|
997
|
+
? applyClientScopeFilter(baseQuery, normalizedClient, isSuperAdmin)
|
|
998
|
+
: baseQuery;
|
|
999
|
+
scopedQuery = applyCustomerScopeFilter(clientScopedQuery, collection, customerId, isSuperAdmin);
|
|
1000
|
+
normalizedPipeline = normalizeAssistantAggregatePipeline(input.pipeline);
|
|
1001
|
+
pipelineWithScope = buildAssistantAggregatePipeline(scopedQuery, normalizedPipeline);
|
|
1002
|
+
normalizedOptions = normalizeAssistantAggregateOptions(input.options);
|
|
1003
|
+
limitedPipeline = applyAssistantAggregateLimit(pipelineWithScope, normalizedOptions.limit);
|
|
1004
|
+
if (containsForbiddenMongoOperators(limitedPipeline)) {
|
|
1005
|
+
throw new Error('AI assistant mongo aggregate: Pipeline contains restricted operators.');
|
|
1006
|
+
}
|
|
1007
|
+
return [4 /*yield*/, db.collection(collection)
|
|
1008
|
+
.aggregate(limitedPipeline, normalizedOptions.aggregateOptions)
|
|
1009
|
+
.toArray()];
|
|
1010
|
+
case 5:
|
|
1011
|
+
documents = _d.sent();
|
|
1012
|
+
if (!!documents.length) return [3 /*break*/, 7];
|
|
1013
|
+
fallback = resolveAggregateDateFieldFallback(limitedPipeline);
|
|
1014
|
+
if (!fallback) return [3 /*break*/, 7];
|
|
1015
|
+
fallbackPipeline = replaceAggregateDateField(limitedPipeline, fallback.from, fallback.to);
|
|
1016
|
+
if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/, 7];
|
|
1017
|
+
return [4 /*yield*/, db.collection(collection)
|
|
1018
|
+
.aggregate(fallbackPipeline, normalizedOptions.aggregateOptions)
|
|
1019
|
+
.toArray()];
|
|
1020
|
+
case 6:
|
|
1021
|
+
fallbackDocs = _d.sent();
|
|
1022
|
+
if (fallbackDocs.length) {
|
|
1023
|
+
documents = fallbackDocs;
|
|
1024
|
+
}
|
|
1025
|
+
_d.label = 7;
|
|
1026
|
+
case 7:
|
|
1027
|
+
sanitizedDocuments = isSuperAdmin
|
|
1028
|
+
? documents
|
|
1029
|
+
: documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
|
|
1030
|
+
return [2 /*return*/, {
|
|
1031
|
+
documents: sanitizedDocuments
|
|
1032
|
+
}];
|
|
1033
|
+
}
|
|
1034
|
+
});
|
|
1035
|
+
});
|
|
1036
|
+
}
|
|
906
1037
|
function ensureAssistantReadAccess(context, permissionView, collection) {
|
|
907
1038
|
return __awaiter(this, void 0, void 0, function () {
|
|
908
1039
|
var idUser, user, isSuperAdmin, normalizedPermission, normalizedCollection;
|
|
@@ -979,6 +1110,162 @@ function normalizeAssistantFindOptions(options) {
|
|
|
979
1110
|
includeTotal: normalized.includeTotal === true
|
|
980
1111
|
};
|
|
981
1112
|
}
|
|
1113
|
+
function normalizeAssistantAggregatePipeline(pipeline) {
|
|
1114
|
+
if (!Array.isArray(pipeline)) {
|
|
1115
|
+
return [];
|
|
1116
|
+
}
|
|
1117
|
+
return pipeline.filter(function (stage) { return stage && typeof stage === 'object' && !Array.isArray(stage); });
|
|
1118
|
+
}
|
|
1119
|
+
function buildAssistantAggregatePipeline(query, pipeline) {
|
|
1120
|
+
var _a;
|
|
1121
|
+
var scopedPipeline = Array.isArray(pipeline) ? __spreadArray([], __read(pipeline), false) : [];
|
|
1122
|
+
if (!query || !Object.keys(query).length) {
|
|
1123
|
+
return scopedPipeline;
|
|
1124
|
+
}
|
|
1125
|
+
if (scopedPipeline.length && ((_a = scopedPipeline[0]) === null || _a === void 0 ? void 0 : _a.$geoNear) && typeof scopedPipeline[0].$geoNear === 'object') {
|
|
1126
|
+
var geoNearStage = __assign({}, scopedPipeline[0].$geoNear);
|
|
1127
|
+
var existingQuery = geoNearStage.query && typeof geoNearStage.query === 'object' ? geoNearStage.query : {};
|
|
1128
|
+
geoNearStage.query = { $and: [existingQuery, query] };
|
|
1129
|
+
return __spreadArray([{ $geoNear: geoNearStage }], __read(scopedPipeline.slice(1)), false);
|
|
1130
|
+
}
|
|
1131
|
+
return __spreadArray([{ $match: query }], __read(scopedPipeline), false);
|
|
1132
|
+
}
|
|
1133
|
+
function normalizeAssistantAggregateOptions(options) {
|
|
1134
|
+
var normalized = options || {};
|
|
1135
|
+
var allowDiskUse = normalized.allowDiskUse === true ? true : undefined;
|
|
1136
|
+
var maxTimeMS = typeof normalized.maxTimeMS === 'number' && normalized.maxTimeMS > 0
|
|
1137
|
+
? (0, common_1.round)(normalized.maxTimeMS)
|
|
1138
|
+
: undefined;
|
|
1139
|
+
var limit = typeof normalized.limit === 'number'
|
|
1140
|
+
? Math.min(Math.max((0, common_1.round)(normalized.limit), 0), AI_ASSISTANT_MONGO_MAX_LIMIT)
|
|
1141
|
+
: undefined;
|
|
1142
|
+
var aggregateOptions = {};
|
|
1143
|
+
if (allowDiskUse !== undefined) {
|
|
1144
|
+
aggregateOptions.allowDiskUse = allowDiskUse;
|
|
1145
|
+
}
|
|
1146
|
+
if (maxTimeMS !== undefined) {
|
|
1147
|
+
aggregateOptions.maxTimeMS = maxTimeMS;
|
|
1148
|
+
}
|
|
1149
|
+
return {
|
|
1150
|
+
aggregateOptions: aggregateOptions,
|
|
1151
|
+
limit: limit
|
|
1152
|
+
};
|
|
1153
|
+
}
|
|
1154
|
+
function findAggregateLimit(pipeline) {
|
|
1155
|
+
for (var i = 0; i < pipeline.length; i += 1) {
|
|
1156
|
+
var stage = pipeline[i];
|
|
1157
|
+
if (!stage || typeof stage !== 'object') {
|
|
1158
|
+
continue;
|
|
1159
|
+
}
|
|
1160
|
+
var limit = stage.$limit;
|
|
1161
|
+
if (typeof limit === 'number' && Number.isFinite(limit)) {
|
|
1162
|
+
return limit;
|
|
1163
|
+
}
|
|
1164
|
+
}
|
|
1165
|
+
return null;
|
|
1166
|
+
}
|
|
1167
|
+
function applyAssistantAggregateLimit(pipeline, limit) {
|
|
1168
|
+
var normalizedPipeline = Array.isArray(pipeline) ? __spreadArray([], __read(pipeline), false) : [];
|
|
1169
|
+
var maxLimit = AI_ASSISTANT_MONGO_MAX_LIMIT;
|
|
1170
|
+
var requestedLimit = typeof limit === 'number' && limit > 0
|
|
1171
|
+
? Math.min(limit, maxLimit)
|
|
1172
|
+
: AI_ASSISTANT_MONGO_DEFAULT_LIMIT;
|
|
1173
|
+
var existingLimit = findAggregateLimit(normalizedPipeline);
|
|
1174
|
+
if (existingLimit === null) {
|
|
1175
|
+
normalizedPipeline.push({ $limit: requestedLimit });
|
|
1176
|
+
return normalizedPipeline;
|
|
1177
|
+
}
|
|
1178
|
+
if (existingLimit > maxLimit) {
|
|
1179
|
+
normalizedPipeline.push({ $limit: maxLimit });
|
|
1180
|
+
}
|
|
1181
|
+
return normalizedPipeline;
|
|
1182
|
+
}
|
|
1183
|
+
function resolveAggregateDateFieldFallback(pipeline) {
|
|
1184
|
+
var dateField = findAggregateDateField(pipeline);
|
|
1185
|
+
if (!dateField) {
|
|
1186
|
+
return null;
|
|
1187
|
+
}
|
|
1188
|
+
var fallback = AI_ASSISTANT_DATE_FALLBACKS[dateField];
|
|
1189
|
+
if (!fallback) {
|
|
1190
|
+
return null;
|
|
1191
|
+
}
|
|
1192
|
+
return { from: dateField, to: fallback };
|
|
1193
|
+
}
|
|
1194
|
+
function findAggregateDateField(pipeline) {
|
|
1195
|
+
var fields = new Set();
|
|
1196
|
+
(pipeline || []).forEach(function (stage) {
|
|
1197
|
+
if (!stage || typeof stage !== 'object') {
|
|
1198
|
+
return;
|
|
1199
|
+
}
|
|
1200
|
+
if (stage.$match && typeof stage.$match === 'object') {
|
|
1201
|
+
collectDateFieldsFromMatch(stage.$match, fields);
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
if (fields.size !== 1) {
|
|
1205
|
+
return null;
|
|
1206
|
+
}
|
|
1207
|
+
return Array.from(fields)[0];
|
|
1208
|
+
}
|
|
1209
|
+
function collectDateFieldsFromMatch(value, fields) {
|
|
1210
|
+
if (!value || typeof value !== 'object') {
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
if (Array.isArray(value)) {
|
|
1214
|
+
value.forEach(function (entry) { return collectDateFieldsFromMatch(entry, fields); });
|
|
1215
|
+
return;
|
|
1216
|
+
}
|
|
1217
|
+
Object.keys(value).forEach(function (key) {
|
|
1218
|
+
var entry = value[key];
|
|
1219
|
+
if (Object.prototype.hasOwnProperty.call(AI_ASSISTANT_DATE_FALLBACKS, key)) {
|
|
1220
|
+
if (hasDateRangeOperators(entry) || entry instanceof Date) {
|
|
1221
|
+
fields.add(key);
|
|
1222
|
+
}
|
|
1223
|
+
return;
|
|
1224
|
+
}
|
|
1225
|
+
if (key.startsWith('$')) {
|
|
1226
|
+
collectDateFieldsFromMatch(entry, fields);
|
|
1227
|
+
return;
|
|
1228
|
+
}
|
|
1229
|
+
if (entry && typeof entry === 'object') {
|
|
1230
|
+
collectDateFieldsFromMatch(entry, fields);
|
|
1231
|
+
}
|
|
1232
|
+
});
|
|
1233
|
+
}
|
|
1234
|
+
function hasDateRangeOperators(value) {
|
|
1235
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
1236
|
+
return false;
|
|
1237
|
+
}
|
|
1238
|
+
return Object.prototype.hasOwnProperty.call(value, '$gte')
|
|
1239
|
+
|| Object.prototype.hasOwnProperty.call(value, '$gt')
|
|
1240
|
+
|| Object.prototype.hasOwnProperty.call(value, '$lte')
|
|
1241
|
+
|| Object.prototype.hasOwnProperty.call(value, '$lt');
|
|
1242
|
+
}
|
|
1243
|
+
function replaceAggregateDateField(pipeline, fromField, toField) {
|
|
1244
|
+
var replacer = function (value) {
|
|
1245
|
+
if (Array.isArray(value)) {
|
|
1246
|
+
return value.map(function (entry) { return replacer(entry); });
|
|
1247
|
+
}
|
|
1248
|
+
if (value instanceof Date) {
|
|
1249
|
+
return value;
|
|
1250
|
+
}
|
|
1251
|
+
if (value && typeof value === 'object') {
|
|
1252
|
+
var next_1 = {};
|
|
1253
|
+
Object.keys(value).forEach(function (key) {
|
|
1254
|
+
var nextKey = key === fromField ? toField : key;
|
|
1255
|
+
next_1[nextKey] = replacer(value[key]);
|
|
1256
|
+
});
|
|
1257
|
+
return next_1;
|
|
1258
|
+
}
|
|
1259
|
+
if (typeof value === 'string') {
|
|
1260
|
+
if (value.startsWith("$".concat(fromField))) {
|
|
1261
|
+
return "$".concat(toField).concat(value.slice(fromField.length + 1));
|
|
1262
|
+
}
|
|
1263
|
+
return value;
|
|
1264
|
+
}
|
|
1265
|
+
return value;
|
|
1266
|
+
};
|
|
1267
|
+
return replacer(pipeline);
|
|
1268
|
+
}
|
|
982
1269
|
function normalizeMongoQuery(query) {
|
|
983
1270
|
var normalized = query && typeof query === 'object' ? query : {};
|
|
984
1271
|
if (containsForbiddenMongoOperators(normalized)) {
|
|
@@ -1640,6 +1927,10 @@ function sanitizeAssistantResponse(value) {
|
|
|
1640
1927
|
}
|
|
1641
1928
|
var withoutBlocks = raw.replace(/```[\\s\\S]*?```/g, '').replace(/`([^`]+)`/g, '$1').trim();
|
|
1642
1929
|
var stripEstimated = function (line) { return line.replace(/\bEstimated (human )?hours:\s*.*$/i, '').trimEnd(); };
|
|
1930
|
+
var isTentativeQueryLine = function (line) {
|
|
1931
|
+
var normalized = line.trim().replace(/^[-*•]+\s*/, '');
|
|
1932
|
+
return /^i\s+(can|will|['’]ll|am going to|['’]m going to)\s+(pull|run|query|get|fetch|look up|retrieve|grab)\b/i.test(normalized);
|
|
1933
|
+
};
|
|
1643
1934
|
var cleanedLines = [];
|
|
1644
1935
|
withoutBlocks.split('\n').forEach(function (line) {
|
|
1645
1936
|
var trimmed = line.trim();
|
|
@@ -1647,6 +1938,9 @@ function sanitizeAssistantResponse(value) {
|
|
|
1647
1938
|
cleanedLines.push(line);
|
|
1648
1939
|
return;
|
|
1649
1940
|
}
|
|
1941
|
+
if (isTentativeQueryLine(line)) {
|
|
1942
|
+
return;
|
|
1943
|
+
}
|
|
1650
1944
|
if (/^work ticket summary:/i.test(trimmed)) {
|
|
1651
1945
|
return;
|
|
1652
1946
|
}
|
|
@@ -2025,6 +2319,12 @@ function sanitizeConfig(source) {
|
|
|
2025
2319
|
max_tokens: normalizeOptionalNumber(source === null || source === void 0 ? void 0 : source.max_tokens)
|
|
2026
2320
|
};
|
|
2027
2321
|
}
|
|
2322
|
+
function resolveClientIdFromConfig(explicit) {
|
|
2323
|
+
var _a;
|
|
2324
|
+
var config = ((_a = resolveio_server_app_1.ResolveIOServer.getServerConfig) === null || _a === void 0 ? void 0 : _a.call(resolveio_server_app_1.ResolveIOServer)) || {};
|
|
2325
|
+
return normalizeOptionalString(explicit)
|
|
2326
|
+
|| normalizeOptionalString(config['CLIENT_ID'] || config['client_id'] || process.env.CLIENT_ID || '');
|
|
2327
|
+
}
|
|
2028
2328
|
function ensureConversation(input, mode) {
|
|
2029
2329
|
return __awaiter(this, void 0, void 0, function () {
|
|
2030
2330
|
var idConversation, existing, now, doc, result;
|
|
@@ -2043,7 +2343,7 @@ function ensureConversation(input, mode) {
|
|
|
2043
2343
|
case 2:
|
|
2044
2344
|
now = new Date();
|
|
2045
2345
|
doc = {
|
|
2046
|
-
id_client:
|
|
2346
|
+
id_client: resolveClientIdFromConfig(input.id_client),
|
|
2047
2347
|
id_app: normalizeOptionalString(input.id_app),
|
|
2048
2348
|
title: 'New Conversation',
|
|
2049
2349
|
mode: mode,
|
|
@@ -2129,7 +2429,9 @@ function normalizeHistoryLimit(value) {
|
|
|
2129
2429
|
return Math.min(Math.max((0, common_1.round)(parsed), 0), 30);
|
|
2130
2430
|
}
|
|
2131
2431
|
function resolveClientId(conversation, inputClientId) {
|
|
2132
|
-
return normalizeOptionalString(inputClientId)
|
|
2432
|
+
return normalizeOptionalString(inputClientId)
|
|
2433
|
+
|| normalizeOptionalString(conversation === null || conversation === void 0 ? void 0 : conversation.id_client)
|
|
2434
|
+
|| resolveClientIdFromConfig();
|
|
2133
2435
|
}
|
|
2134
2436
|
function estimateUsage(messages, responseText, model) {
|
|
2135
2437
|
var inputTokens = (0, tokenizer_1.countChatTokens)(messages, model);
|