@resolveio/server-lib 20.15.3 → 20.15.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/methods/ai-terminal.js +760 -159
- package/methods/ai-terminal.js.map +1 -1
- package/package.json +1 -1
package/methods/ai-terminal.js
CHANGED
|
@@ -133,7 +133,7 @@ var DEFAULT_MAX_FILE_MB = 50;
|
|
|
133
133
|
var DEFAULT_MAX_TOTAL_MB = 100;
|
|
134
134
|
var DEFAULT_MAX_ATTACHMENT_CHARS = 12000;
|
|
135
135
|
var DEFAULT_MAX_TOTAL_ATTACHMENT_CHARS = 40000;
|
|
136
|
-
var DEFAULT_CODEX_MODEL = 'gpt-5.
|
|
136
|
+
var DEFAULT_CODEX_MODEL = 'gpt-5.1-codex-mini';
|
|
137
137
|
var DEFAULT_CODEX_TIMEOUT_MS = 180000;
|
|
138
138
|
var AI_ASSISTANT_MONGO_DEFAULT_LIMIT = 20;
|
|
139
139
|
var AI_ASSISTANT_MONGO_MAX_LIMIT = 200;
|
|
@@ -199,6 +199,51 @@ var AI_ASSISTANT_SENSITIVE_FIELDS = [
|
|
|
199
199
|
'roles'
|
|
200
200
|
];
|
|
201
201
|
var AI_ASSISTANT_CLIENT_SCOPE_CACHE = new Map();
|
|
202
|
+
var AI_ASSISTANT_COLLECTION_CACHE = new Map();
|
|
203
|
+
var AI_ASSISTANT_COLLECTION_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
204
|
+
var AI_ASSISTANT_COLLECTION_STOPWORDS = new Set([
|
|
205
|
+
'the',
|
|
206
|
+
'a',
|
|
207
|
+
'an',
|
|
208
|
+
'of',
|
|
209
|
+
'for',
|
|
210
|
+
'by',
|
|
211
|
+
'with',
|
|
212
|
+
'and',
|
|
213
|
+
'or',
|
|
214
|
+
'to',
|
|
215
|
+
'from',
|
|
216
|
+
'in',
|
|
217
|
+
'on',
|
|
218
|
+
'at',
|
|
219
|
+
'last',
|
|
220
|
+
'recent',
|
|
221
|
+
'today',
|
|
222
|
+
'week',
|
|
223
|
+
'month',
|
|
224
|
+
'year',
|
|
225
|
+
'this',
|
|
226
|
+
'that',
|
|
227
|
+
'these',
|
|
228
|
+
'those',
|
|
229
|
+
'show',
|
|
230
|
+
'list',
|
|
231
|
+
'get',
|
|
232
|
+
'give',
|
|
233
|
+
'how',
|
|
234
|
+
'many',
|
|
235
|
+
'count',
|
|
236
|
+
'total',
|
|
237
|
+
'breakdown',
|
|
238
|
+
'group',
|
|
239
|
+
'grouped',
|
|
240
|
+
'per',
|
|
241
|
+
'open',
|
|
242
|
+
'closed',
|
|
243
|
+
'completed',
|
|
244
|
+
'missing',
|
|
245
|
+
'overdue'
|
|
246
|
+
]);
|
|
202
247
|
var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
203
248
|
'You are the ResolveIO in-app AI assistant running with read-only access to the codebase.',
|
|
204
249
|
'Core rules:',
|
|
@@ -209,11 +254,16 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
209
254
|
'- If the user has a customer portal scope (other.id_customer), only discuss that customer\'s data and what is visible in their customer portal. Never reference other customers or internal/admin-only data. If asked for anything outside the portal, say it isn\'t available.',
|
|
210
255
|
'- Do not assist with hacking, bypassing security, or abuse.',
|
|
211
256
|
'Accuracy & tools:',
|
|
257
|
+
'- Step 1 (always): determine the target collections/models/modules/workflows using context, routes, and collection hints. Assume the user is non-technical and will not provide internal names.',
|
|
258
|
+
'- Map user wording to internal collections/fields yourself. Do not ask for property names unless required to run a query.',
|
|
212
259
|
'- Do not guess or invent collections/fields. If unsure, verify in the codebase or run a small Mongo read (limit 1-5) to learn the shape.',
|
|
213
260
|
'- Prefer running a small Mongo read over asking multiple questions.',
|
|
261
|
+
'- For any data request (counts, lists, breakdowns, recent/last items), you MUST run a MONGO_READ or MONGO_AGG before answering.',
|
|
214
262
|
'- Ask at most one clarifying question only when required to run a query or resolve missing details.',
|
|
215
263
|
'- If a field starts with id_ and refers to another collection, treat it as a foreign key and look up the related record when needed.',
|
|
264
|
+
'- When the user provides a customer, well, or chemical name, use case-insensitive regex matching to find it. Assume the name exists and try to match it before asking questions.',
|
|
216
265
|
'- Use the codebase context to choose correct collections/fields/workflows and use MONGO_READ/MONGO_AGG to answer with real data when needed.',
|
|
266
|
+
'- Assume a relevant collection exists; if verification reads return zero data, report no data found instead of interrogating the user.',
|
|
217
267
|
'- For direct questions, answer first. Ask a single follow-up only if required to proceed.',
|
|
218
268
|
'Data Presentation:',
|
|
219
269
|
'- Output plain Markdown (NO triple backticks).',
|
|
@@ -224,6 +274,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
224
274
|
'- If `_id` & `__v` & `id_<other collection _id property>` is needed, show it as `id` and shorten (e.g., first 6-8 chars) unless asked otherwise.',
|
|
225
275
|
'- Rename `createdAt` to `Created At` and `updatedAt` to `Updated At` in tables.',
|
|
226
276
|
'Response style:',
|
|
277
|
+
'- Respond in English only. Do not include non-English text or characters unless required for JSON, links, or tool directives.',
|
|
227
278
|
'- Keep responses concise: answer first, then 3-8 bullets, then a table when data is involved.',
|
|
228
279
|
'- Prefer high-level explanations and point to routes instead of code. Only mention file paths if explicitly requested.',
|
|
229
280
|
'- When asked where to do something, give the exact screen name and the in-app route as a standalone path starting with "/" so it can be clicked.',
|
|
@@ -261,7 +312,8 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
261
312
|
'- When grouping by fields that can be arrays (drivers, deliveries, routes, chemicals), $unwind first and group by both id and name when available.',
|
|
262
313
|
'- Use MONGO_READ/MONGO_AGG only to produce summaries/snapshots/health checks (not raw dumps) when permitted.',
|
|
263
314
|
'- If the user explicitly asks for IDs, set options.includeIds: true.',
|
|
264
|
-
'-
|
|
315
|
+
'- If a data question returns zero results, verify the collection/date field with a tiny read (limit 1-5) or a date field fallback before concluding there is no data.',
|
|
316
|
+
'- Keep responses concise and use the configured reasoning effort level (default low).'
|
|
265
317
|
].join('\n');
|
|
266
318
|
var AI_FORM_PATCH_SYSTEM_PROMPT = [
|
|
267
319
|
'You are the ResolveIO form patch assistant.',
|
|
@@ -800,10 +852,10 @@ function executeAiFormPatch(payload, context) {
|
|
|
800
852
|
}
|
|
801
853
|
function executeAiAssistantCodexRun(payload, context) {
|
|
802
854
|
return __awaiter(this, void 0, void 0, function () {
|
|
803
|
-
var input, message, requestId, guardrail, conversation_2, now_2, userMsg, assistantMsg, user, isSuperAdmin, hasInvoiceAccess, customerId, conversation, now, attachments, attachmentData, historyLimit, history, _a, historyLines, assistantContext, prompt, workspaceRoot, codexConfig, runOptions, userDoc, initialProgress, assistantDoc, insertResult, assistantMessageId, progressTracker, streamProgress, assistantContent, toolResult, responseText, directive, cleanedResponseText, toolRequest, toolResponse,
|
|
804
|
-
var
|
|
805
|
-
return __generator(this, function (
|
|
806
|
-
switch (
|
|
855
|
+
var input, message, requestId, guardrail, conversation_2, now_2, userMsg, assistantMsg, user, isSuperAdmin, hasInvoiceAccess, customerId, conversation, now, attachments, attachmentData, historyLimit, history, _a, historyLines, collectionHints, dbName, db, hintText, _b, assistantContext, prompt, workspaceRoot, codexConfig, runOptions, userDoc, initialProgress, assistantDoc, insertResult, assistantMessageId, progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, dataQuestion, lastDirective, toolResponseDebug, toolError, responseText, directive, directiveSourceText, directivePrompt, directiveText, forcedDirective, _c, cleanedResponseText, toolRequest, toolResponse, _d, toolPayload, followupPrompt, followupText, _e, error_1, error_2, finalNow, finalMetadata, finalAssistantDoc;
|
|
856
|
+
var _f, _g, _h;
|
|
857
|
+
return __generator(this, function (_j) {
|
|
858
|
+
switch (_j.label) {
|
|
807
859
|
case 0:
|
|
808
860
|
input = payload || {};
|
|
809
861
|
message = normalizeOptionalString(input.message);
|
|
@@ -818,7 +870,7 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
818
870
|
if (!(guardrail === null || guardrail === void 0 ? void 0 : guardrail.blocked)) return [3 /*break*/, 5];
|
|
819
871
|
return [4 /*yield*/, ensureConversation(input, 'codex')];
|
|
820
872
|
case 1:
|
|
821
|
-
conversation_2 =
|
|
873
|
+
conversation_2 = _j.sent();
|
|
822
874
|
now_2 = new Date();
|
|
823
875
|
userMsg = {
|
|
824
876
|
id_conversation: conversation_2._id,
|
|
@@ -838,13 +890,13 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
838
890
|
};
|
|
839
891
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userMsg)];
|
|
840
892
|
case 2:
|
|
841
|
-
|
|
893
|
+
_j.sent();
|
|
842
894
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(assistantMsg)];
|
|
843
895
|
case 3:
|
|
844
|
-
|
|
896
|
+
_j.sent();
|
|
845
897
|
return [4 /*yield*/, touchConversation(conversation_2._id, now_2)];
|
|
846
898
|
case 4:
|
|
847
|
-
|
|
899
|
+
_j.sent();
|
|
848
900
|
return [2 /*return*/, {
|
|
849
901
|
conversation: conversation_2,
|
|
850
902
|
message: assistantMsg,
|
|
@@ -852,27 +904,27 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
852
904
|
}];
|
|
853
905
|
case 5: return [4 /*yield*/, user_collection_1.Users.findById(context === null || context === void 0 ? void 0 : context.id_user)];
|
|
854
906
|
case 6:
|
|
855
|
-
user =
|
|
856
|
-
isSuperAdmin = !!((
|
|
907
|
+
user = _j.sent();
|
|
908
|
+
isSuperAdmin = !!((_f = user === null || user === void 0 ? void 0 : user.roles) === null || _f === void 0 ? void 0 : _f.super_admin);
|
|
857
909
|
hasInvoiceAccess = userHasInvoiceAccess(user);
|
|
858
|
-
customerId = normalizeOptionalString((
|
|
910
|
+
customerId = normalizeOptionalString((_g = user === null || user === void 0 ? void 0 : user.other) === null || _g === void 0 ? void 0 : _g.id_customer);
|
|
859
911
|
return [4 /*yield*/, ensureConversation(input, 'codex')];
|
|
860
912
|
case 7:
|
|
861
|
-
conversation =
|
|
913
|
+
conversation = _j.sent();
|
|
862
914
|
now = new Date();
|
|
863
915
|
attachments = Array.isArray(input.attachments) ? input.attachments : [];
|
|
864
916
|
return [4 /*yield*/, readAttachmentContents(attachments)];
|
|
865
917
|
case 8:
|
|
866
|
-
attachmentData =
|
|
918
|
+
attachmentData = _j.sent();
|
|
867
919
|
historyLimit = normalizeHistoryLimit(input.max_history);
|
|
868
920
|
if (!(historyLimit > 0)) return [3 /*break*/, 10];
|
|
869
921
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.find({ id_conversation: conversation._id, role: { $in: ['user', 'assistant'] } }, { sort: { createdAt: 1 }, limit: historyLimit * 2 })];
|
|
870
922
|
case 9:
|
|
871
|
-
_a =
|
|
923
|
+
_a = _j.sent();
|
|
872
924
|
return [3 /*break*/, 11];
|
|
873
925
|
case 10:
|
|
874
926
|
_a = [];
|
|
875
|
-
|
|
927
|
+
_j.label = 11;
|
|
876
928
|
case 11:
|
|
877
929
|
history = _a;
|
|
878
930
|
historyLines = [];
|
|
@@ -883,11 +935,35 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
883
935
|
historyLines.push("".concat(role, ": ").concat(content));
|
|
884
936
|
}
|
|
885
937
|
});
|
|
886
|
-
|
|
938
|
+
collectionHints = [];
|
|
939
|
+
_j.label = 12;
|
|
940
|
+
case 12:
|
|
941
|
+
_j.trys.push([12, 14, , 15]);
|
|
942
|
+
dbName = resolveAssistantDatabaseName(undefined, input.mongo);
|
|
943
|
+
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
944
|
+
hintText = [
|
|
945
|
+
message,
|
|
946
|
+
normalizeOptionalString((_h = input === null || input === void 0 ? void 0 : input.context) === null || _h === void 0 ? void 0 : _h.route)
|
|
947
|
+
].filter(Boolean).join(' ');
|
|
948
|
+
return [4 /*yield*/, resolveAssistantCollectionHints(hintText, dbName, db)];
|
|
949
|
+
case 13:
|
|
950
|
+
collectionHints = _j.sent();
|
|
951
|
+
return [3 /*break*/, 15];
|
|
952
|
+
case 14:
|
|
953
|
+
_b = _j.sent();
|
|
954
|
+
collectionHints = [];
|
|
955
|
+
return [3 /*break*/, 15];
|
|
956
|
+
case 15:
|
|
957
|
+
assistantContext = buildAssistantContext(input, {
|
|
958
|
+
isSuperAdmin: isSuperAdmin,
|
|
959
|
+
hasInvoiceAccess: hasInvoiceAccess,
|
|
960
|
+
customerId: customerId,
|
|
961
|
+
collectionHints: collectionHints
|
|
962
|
+
});
|
|
887
963
|
prompt = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
|
|
888
964
|
return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
|
|
889
|
-
case
|
|
890
|
-
workspaceRoot =
|
|
965
|
+
case 16:
|
|
966
|
+
workspaceRoot = _j.sent();
|
|
891
967
|
codexConfig = resolveCodexSettings();
|
|
892
968
|
runOptions = {
|
|
893
969
|
timeoutMs: resolveCodexTimeoutMs(),
|
|
@@ -895,7 +971,7 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
895
971
|
workingDirectory: workspaceRoot,
|
|
896
972
|
sandboxMode: 'read-only',
|
|
897
973
|
skipGitRepoCheck: true,
|
|
898
|
-
modelReasoningEffort:
|
|
974
|
+
modelReasoningEffort: resolveCodexThoughtLevel(),
|
|
899
975
|
networkAccessEnabled: false,
|
|
900
976
|
webSearchMode: 'disabled',
|
|
901
977
|
webSearchEnabled: false,
|
|
@@ -921,83 +997,128 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
921
997
|
updatedAt: now
|
|
922
998
|
};
|
|
923
999
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userDoc)];
|
|
924
|
-
case
|
|
925
|
-
|
|
1000
|
+
case 17:
|
|
1001
|
+
_j.sent();
|
|
926
1002
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(assistantDoc)];
|
|
927
|
-
case
|
|
928
|
-
insertResult =
|
|
1003
|
+
case 18:
|
|
1004
|
+
insertResult = _j.sent();
|
|
929
1005
|
assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
|
|
930
1006
|
progressTracker = createAssistantProgressTracker(assistantMessageId, initialProgress);
|
|
931
1007
|
streamProgress = createAssistantStreamProgressHandler(progressTracker);
|
|
932
1008
|
assistantContent = '';
|
|
933
1009
|
toolResult = null;
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1010
|
+
assistantDebug = null;
|
|
1011
|
+
directiveSource = 'none';
|
|
1012
|
+
dataQuestion = isAssistantDataQuestion(message);
|
|
1013
|
+
lastDirective = null;
|
|
1014
|
+
toolResponseDebug = null;
|
|
1015
|
+
toolError = null;
|
|
1016
|
+
_j.label = 19;
|
|
1017
|
+
case 19:
|
|
1018
|
+
_j.trys.push([19, 38, 39, 40]);
|
|
937
1019
|
return [4 /*yield*/, runCodexInWorkerThread(prompt, runOptions, codexConfig, streamProgress)];
|
|
938
|
-
case
|
|
939
|
-
responseText =
|
|
1020
|
+
case 20:
|
|
1021
|
+
responseText = _j.sent();
|
|
940
1022
|
directive = extractAssistantMongoDirective(responseText);
|
|
941
|
-
|
|
1023
|
+
directiveSourceText = responseText;
|
|
1024
|
+
if (directive) {
|
|
1025
|
+
directiveSource = 'model';
|
|
1026
|
+
lastDirective = directive;
|
|
1027
|
+
}
|
|
1028
|
+
if (!(!directive && dataQuestion)) return [3 /*break*/, 24];
|
|
1029
|
+
directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
|
|
1030
|
+
_j.label = 21;
|
|
1031
|
+
case 21:
|
|
1032
|
+
_j.trys.push([21, 23, , 24]);
|
|
1033
|
+
return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
|
|
1034
|
+
case 22:
|
|
1035
|
+
directiveText = _j.sent();
|
|
1036
|
+
forcedDirective = extractAssistantMongoDirective(directiveText);
|
|
1037
|
+
if (forcedDirective) {
|
|
1038
|
+
directive = forcedDirective;
|
|
1039
|
+
directiveSourceText = directiveText;
|
|
1040
|
+
directiveSource = 'forced';
|
|
1041
|
+
lastDirective = forcedDirective;
|
|
1042
|
+
}
|
|
1043
|
+
return [3 /*break*/, 24];
|
|
1044
|
+
case 23:
|
|
1045
|
+
_c = _j.sent();
|
|
1046
|
+
return [3 /*break*/, 24];
|
|
1047
|
+
case 24:
|
|
1048
|
+
cleanedResponseText = (directive === null || directive === void 0 ? void 0 : directive.cleaned) || directiveSourceText;
|
|
942
1049
|
assistantContent = sanitizeAssistantResponse(cleanedResponseText);
|
|
943
|
-
if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/,
|
|
1050
|
+
if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 36];
|
|
944
1051
|
toolRequest = buildAssistantToolRequest(directive, input);
|
|
945
1052
|
progressTracker.push('Looking up Data');
|
|
946
|
-
|
|
947
|
-
case
|
|
948
|
-
|
|
949
|
-
if (!(directive.type === 'aggregate')) return [3 /*break*/,
|
|
1053
|
+
_j.label = 25;
|
|
1054
|
+
case 25:
|
|
1055
|
+
_j.trys.push([25, 34, , 35]);
|
|
1056
|
+
if (!(directive.type === 'aggregate')) return [3 /*break*/, 27];
|
|
950
1057
|
return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
|
|
951
|
-
case
|
|
952
|
-
|
|
953
|
-
return [3 /*break*/,
|
|
954
|
-
case
|
|
955
|
-
case
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
case
|
|
959
|
-
toolResponse =
|
|
1058
|
+
case 26:
|
|
1059
|
+
_d = _j.sent();
|
|
1060
|
+
return [3 /*break*/, 29];
|
|
1061
|
+
case 27: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
|
|
1062
|
+
case 28:
|
|
1063
|
+
_d = _j.sent();
|
|
1064
|
+
_j.label = 29;
|
|
1065
|
+
case 29:
|
|
1066
|
+
toolResponse = _d;
|
|
1067
|
+
toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
|
|
1068
|
+
? toolResponse.debug
|
|
1069
|
+
: null;
|
|
960
1070
|
toolPayload = buildAssistantToolResultPayload(directive, toolResponse);
|
|
961
1071
|
toolResult = toolPayload.result;
|
|
962
1072
|
progressTracker.push('Drafting response');
|
|
963
1073
|
followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
|
|
964
|
-
|
|
965
|
-
case
|
|
966
|
-
|
|
1074
|
+
_j.label = 30;
|
|
1075
|
+
case 30:
|
|
1076
|
+
_j.trys.push([30, 32, , 33]);
|
|
967
1077
|
return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
|
|
968
|
-
case
|
|
969
|
-
followupText =
|
|
1078
|
+
case 31:
|
|
1079
|
+
followupText = _j.sent();
|
|
970
1080
|
assistantContent = sanitizeAssistantResponse(followupText);
|
|
971
|
-
return [3 /*break*/,
|
|
972
|
-
case
|
|
973
|
-
|
|
1081
|
+
return [3 /*break*/, 33];
|
|
1082
|
+
case 32:
|
|
1083
|
+
_e = _j.sent();
|
|
974
1084
|
assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
|
|
975
|
-
return [3 /*break*/,
|
|
976
|
-
case
|
|
977
|
-
case
|
|
978
|
-
error_1 =
|
|
1085
|
+
return [3 /*break*/, 33];
|
|
1086
|
+
case 33: return [3 /*break*/, 35];
|
|
1087
|
+
case 34:
|
|
1088
|
+
error_1 = _j.sent();
|
|
979
1089
|
assistantContent = buildAssistantToolErrorMessage(error_1, directive, toolRequest);
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
case
|
|
1090
|
+
toolError = error_1;
|
|
1091
|
+
return [3 /*break*/, 35];
|
|
1092
|
+
case 35: return [3 /*break*/, 37];
|
|
1093
|
+
case 36:
|
|
983
1094
|
progressTracker.push('Drafting response');
|
|
984
|
-
|
|
985
|
-
case
|
|
986
|
-
case
|
|
987
|
-
error_2 =
|
|
1095
|
+
_j.label = 37;
|
|
1096
|
+
case 37: return [3 /*break*/, 40];
|
|
1097
|
+
case 38:
|
|
1098
|
+
error_2 = _j.sent();
|
|
988
1099
|
assistantContent = buildAssistantCodexErrorMessage(error_2);
|
|
989
|
-
return [3 /*break*/,
|
|
990
|
-
case
|
|
1100
|
+
return [3 /*break*/, 40];
|
|
1101
|
+
case 39:
|
|
991
1102
|
progressTracker.stop();
|
|
992
1103
|
return [7 /*endfinally*/];
|
|
993
|
-
case
|
|
1104
|
+
case 40:
|
|
994
1105
|
if (!assistantContent) {
|
|
995
1106
|
assistantContent = buildAssistantCodexErrorMessage(null);
|
|
996
1107
|
}
|
|
997
1108
|
finalNow = new Date();
|
|
998
|
-
|
|
1109
|
+
if (isSuperAdmin) {
|
|
1110
|
+
assistantDebug = buildAssistantDebugPayload({
|
|
1111
|
+
dataQuestion: dataQuestion,
|
|
1112
|
+
directive: lastDirective,
|
|
1113
|
+
directiveSource: directiveSource,
|
|
1114
|
+
toolResult: toolResult,
|
|
1115
|
+
toolResponseDebug: toolResponseDebug,
|
|
1116
|
+
toolError: toolError
|
|
1117
|
+
});
|
|
1118
|
+
}
|
|
1119
|
+
finalMetadata = __assign(__assign(__assign({ model: resolveCodexModel() }, (requestId ? { request_id: requestId } : {})), (toolResult ? { tool_result: toolResult } : {})), (assistantDebug ? { debug: assistantDebug } : {}));
|
|
999
1120
|
finalAssistantDoc = __assign(__assign({}, assistantDoc), { _id: assistantMessageId, content: assistantContent, metadata: finalMetadata, updatedAt: finalNow });
|
|
1000
|
-
if (!assistantMessageId) return [3 /*break*/,
|
|
1121
|
+
if (!assistantMessageId) return [3 /*break*/, 42];
|
|
1001
1122
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: assistantMessageId }, {
|
|
1002
1123
|
$set: {
|
|
1003
1124
|
content: assistantContent,
|
|
@@ -1005,43 +1126,47 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1005
1126
|
updatedAt: finalNow
|
|
1006
1127
|
}
|
|
1007
1128
|
})];
|
|
1008
|
-
case
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
case
|
|
1012
|
-
case
|
|
1013
|
-
|
|
1014
|
-
if (!(input.delete_files_after_run !== false)) return [3 /*break*/,
|
|
1129
|
+
case 41:
|
|
1130
|
+
_j.sent();
|
|
1131
|
+
_j.label = 42;
|
|
1132
|
+
case 42: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
|
|
1133
|
+
case 43:
|
|
1134
|
+
_j.sent();
|
|
1135
|
+
if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 45];
|
|
1015
1136
|
return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
|
|
1016
|
-
case
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
case
|
|
1137
|
+
case 44:
|
|
1138
|
+
_j.sent();
|
|
1139
|
+
_j.label = 45;
|
|
1140
|
+
case 45: return [2 /*return*/, __assign({ conversation: conversation, message: finalAssistantDoc }, (toolResult ? { tool_result: toolResult } : {}))];
|
|
1020
1141
|
}
|
|
1021
1142
|
});
|
|
1022
1143
|
});
|
|
1023
1144
|
}
|
|
1024
1145
|
function executeAiAssistantMongoRead(payload, context) {
|
|
1025
1146
|
return __awaiter(this, void 0, void 0, function () {
|
|
1026
|
-
var input, collection, _a, user, isSuperAdmin, customerId,
|
|
1147
|
+
var input, rawCollection, dbName, db, collectionResolution, collection, _a, user, isSuperAdmin, customerId, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalized, documents, executedQuery, fallbackMeta, dateFallback, fallbackQuery, fallbackDocs, total, sanitizedDocuments, includeIds, display;
|
|
1027
1148
|
var _c, _d;
|
|
1028
1149
|
return __generator(this, function (_e) {
|
|
1029
1150
|
switch (_e.label) {
|
|
1030
1151
|
case 0:
|
|
1031
1152
|
input = payload || {};
|
|
1032
|
-
|
|
1033
|
-
if (!
|
|
1153
|
+
rawCollection = normalizeOptionalString(input.collection);
|
|
1154
|
+
if (!rawCollection) {
|
|
1034
1155
|
throw new Error('AI assistant mongo read: Collection is required.');
|
|
1035
1156
|
}
|
|
1036
|
-
|
|
1157
|
+
dbName = resolveAssistantDatabaseName(input.database, input.mongo);
|
|
1158
|
+
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
1159
|
+
return [4 /*yield*/, resolveAssistantCollectionName(db, dbName, rawCollection)];
|
|
1037
1160
|
case 1:
|
|
1161
|
+
collectionResolution = _e.sent();
|
|
1162
|
+
collection = collectionResolution.name || rawCollection;
|
|
1163
|
+
return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
|
|
1164
|
+
case 2:
|
|
1038
1165
|
_a = _e.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
|
|
1039
1166
|
if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
|
|
1040
1167
|
throw new Error('AI assistant mongo read: Access denied.');
|
|
1041
1168
|
}
|
|
1042
1169
|
customerId = normalizeOptionalString((_c = user === null || user === void 0 ? void 0 : user.other) === null || _c === void 0 ? void 0 : _c.id_customer);
|
|
1043
|
-
dbName = resolveAssistantDatabaseName(input.database, input.mongo);
|
|
1044
|
-
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
1045
1170
|
baseQuery = normalizeMongoQuery(input.query);
|
|
1046
1171
|
if (!isSuperAdmin && (collection === 'users' || collection === 'user-versions')) {
|
|
1047
1172
|
userId = normalizeOptionalString(user === null || user === void 0 ? void 0 : user._id);
|
|
@@ -1053,15 +1178,15 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
1053
1178
|
};
|
|
1054
1179
|
}
|
|
1055
1180
|
normalizedClient = normalizeOptionalString(input.id_client);
|
|
1056
|
-
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/,
|
|
1181
|
+
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 4];
|
|
1057
1182
|
return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
|
|
1058
|
-
case 2:
|
|
1059
|
-
_b = _e.sent();
|
|
1060
|
-
return [3 /*break*/, 4];
|
|
1061
1183
|
case 3:
|
|
1062
|
-
_b =
|
|
1063
|
-
|
|
1184
|
+
_b = _e.sent();
|
|
1185
|
+
return [3 /*break*/, 5];
|
|
1064
1186
|
case 4:
|
|
1187
|
+
_b = false;
|
|
1188
|
+
_e.label = 5;
|
|
1189
|
+
case 5:
|
|
1065
1190
|
shouldScopeByClient = _b;
|
|
1066
1191
|
clientScopedQuery = shouldScopeByClient
|
|
1067
1192
|
? applyClientScopeFilter(baseQuery, normalizedClient, isSuperAdmin)
|
|
@@ -1069,15 +1194,32 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
1069
1194
|
scopedQuery = applyCustomerScopeFilter(clientScopedQuery, collection, customerId, isSuperAdmin);
|
|
1070
1195
|
normalized = normalizeAssistantFindOptions(input.options);
|
|
1071
1196
|
return [4 /*yield*/, db.collection(collection).find(scopedQuery, normalized.findOptions).toArray()];
|
|
1072
|
-
case
|
|
1197
|
+
case 6:
|
|
1073
1198
|
documents = _e.sent();
|
|
1199
|
+
executedQuery = scopedQuery;
|
|
1200
|
+
fallbackMeta = {};
|
|
1201
|
+
if (!!documents.length) return [3 /*break*/, 8];
|
|
1202
|
+
dateFallback = resolveQueryDateFieldFallback(scopedQuery);
|
|
1203
|
+
if (!dateFallback) return [3 /*break*/, 8];
|
|
1204
|
+
fallbackQuery = replaceQueryField(scopedQuery, dateFallback.from, dateFallback.to);
|
|
1205
|
+
fallbackMeta.dateField = __assign(__assign({}, dateFallback), { attempted: true, used: false });
|
|
1206
|
+
return [4 /*yield*/, db.collection(collection).find(fallbackQuery, normalized.findOptions).toArray()];
|
|
1207
|
+
case 7:
|
|
1208
|
+
fallbackDocs = _e.sent();
|
|
1209
|
+
if (fallbackDocs.length) {
|
|
1210
|
+
documents = fallbackDocs;
|
|
1211
|
+
executedQuery = fallbackQuery;
|
|
1212
|
+
fallbackMeta.dateField.used = true;
|
|
1213
|
+
}
|
|
1214
|
+
_e.label = 8;
|
|
1215
|
+
case 8:
|
|
1074
1216
|
total = null;
|
|
1075
|
-
if (!normalized.includeTotal) return [3 /*break*/,
|
|
1076
|
-
return [4 /*yield*/, db.collection(collection).countDocuments(
|
|
1077
|
-
case
|
|
1217
|
+
if (!normalized.includeTotal) return [3 /*break*/, 10];
|
|
1218
|
+
return [4 /*yield*/, db.collection(collection).countDocuments(executedQuery)];
|
|
1219
|
+
case 9:
|
|
1078
1220
|
total = _e.sent();
|
|
1079
|
-
_e.label =
|
|
1080
|
-
case
|
|
1221
|
+
_e.label = 10;
|
|
1222
|
+
case 10:
|
|
1081
1223
|
sanitizedDocuments = isSuperAdmin
|
|
1082
1224
|
? documents
|
|
1083
1225
|
: documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
|
|
@@ -1093,10 +1235,16 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
1093
1235
|
return [2 /*return*/, __assign({ documents: sanitizedDocuments, total: total, display: display }, (isSuperAdmin ? {
|
|
1094
1236
|
debug: {
|
|
1095
1237
|
collection: collection,
|
|
1238
|
+
collectionRequested: rawCollection,
|
|
1239
|
+
collectionResolved: collection,
|
|
1240
|
+
collectionMatched: collectionResolution.matched,
|
|
1241
|
+
collectionCandidates: collectionResolution.candidates,
|
|
1242
|
+
collectionScore: collectionResolution.score,
|
|
1096
1243
|
database: dbName,
|
|
1097
|
-
query:
|
|
1244
|
+
query: executedQuery,
|
|
1098
1245
|
options: normalized.findOptions,
|
|
1099
|
-
includeTotal: normalized.includeTotal
|
|
1246
|
+
includeTotal: normalized.includeTotal,
|
|
1247
|
+
fallbacks: fallbackMeta
|
|
1100
1248
|
}
|
|
1101
1249
|
} : {}))];
|
|
1102
1250
|
}
|
|
@@ -1105,25 +1253,29 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
1105
1253
|
}
|
|
1106
1254
|
function executeAiAssistantMongoAggregate(payload, context) {
|
|
1107
1255
|
return __awaiter(this, void 0, void 0, function () {
|
|
1108
|
-
var input, collection, _a, user, isSuperAdmin, customerId,
|
|
1256
|
+
var input, rawCollection, dbName, db, collectionResolution, collection, _a, user, isSuperAdmin, customerId, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, dateField, documents, executedPipeline, fallbackMeta, fallback, fallbackPipeline, fallbackDocs, createdFallback, createdPipeline, createdDocs, unwindFallback, fallbackPipeline, fallbackDocs, sanitizedDocuments, includeIds, display;
|
|
1109
1257
|
var _c, _d;
|
|
1110
1258
|
return __generator(this, function (_e) {
|
|
1111
1259
|
switch (_e.label) {
|
|
1112
1260
|
case 0:
|
|
1113
1261
|
input = payload || {};
|
|
1114
|
-
|
|
1115
|
-
if (!
|
|
1262
|
+
rawCollection = normalizeOptionalString(input.collection);
|
|
1263
|
+
if (!rawCollection) {
|
|
1116
1264
|
throw new Error('AI assistant mongo aggregate: Collection is required.');
|
|
1117
1265
|
}
|
|
1118
|
-
|
|
1266
|
+
dbName = resolveAssistantDatabaseName(input.database, input.mongo);
|
|
1267
|
+
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
1268
|
+
return [4 /*yield*/, resolveAssistantCollectionName(db, dbName, rawCollection)];
|
|
1119
1269
|
case 1:
|
|
1270
|
+
collectionResolution = _e.sent();
|
|
1271
|
+
collection = collectionResolution.name || rawCollection;
|
|
1272
|
+
return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
|
|
1273
|
+
case 2:
|
|
1120
1274
|
_a = _e.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
|
|
1121
1275
|
if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
|
|
1122
1276
|
throw new Error('AI assistant mongo aggregate: Access denied.');
|
|
1123
1277
|
}
|
|
1124
1278
|
customerId = normalizeOptionalString((_c = user === null || user === void 0 ? void 0 : user.other) === null || _c === void 0 ? void 0 : _c.id_customer);
|
|
1125
|
-
dbName = resolveAssistantDatabaseName(input.database, input.mongo);
|
|
1126
|
-
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
1127
1279
|
baseQuery = normalizeMongoQuery(input.query);
|
|
1128
1280
|
if (!isSuperAdmin && (collection === 'users' || collection === 'user-versions')) {
|
|
1129
1281
|
userId = normalizeOptionalString(user === null || user === void 0 ? void 0 : user._id);
|
|
@@ -1135,15 +1287,15 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
1135
1287
|
};
|
|
1136
1288
|
}
|
|
1137
1289
|
normalizedClient = normalizeOptionalString(input.id_client);
|
|
1138
|
-
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/,
|
|
1290
|
+
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 4];
|
|
1139
1291
|
return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
|
|
1140
|
-
case 2:
|
|
1141
|
-
_b = _e.sent();
|
|
1142
|
-
return [3 /*break*/, 4];
|
|
1143
1292
|
case 3:
|
|
1144
|
-
_b =
|
|
1145
|
-
|
|
1293
|
+
_b = _e.sent();
|
|
1294
|
+
return [3 /*break*/, 5];
|
|
1146
1295
|
case 4:
|
|
1296
|
+
_b = false;
|
|
1297
|
+
_e.label = 5;
|
|
1298
|
+
case 5:
|
|
1147
1299
|
shouldScopeByClient = _b;
|
|
1148
1300
|
clientScopedQuery = shouldScopeByClient
|
|
1149
1301
|
? applyClientScopeFilter(baseQuery, normalizedClient, isSuperAdmin)
|
|
@@ -1160,63 +1312,63 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
1160
1312
|
return [4 /*yield*/, db.collection(collection)
|
|
1161
1313
|
.aggregate(limitedPipeline, normalizedOptions.aggregateOptions)
|
|
1162
1314
|
.toArray()];
|
|
1163
|
-
case
|
|
1315
|
+
case 6:
|
|
1164
1316
|
documents = _e.sent();
|
|
1165
1317
|
executedPipeline = limitedPipeline;
|
|
1166
1318
|
fallbackMeta = {};
|
|
1167
|
-
if (!(!documents.length && dateField)) return [3 /*break*/,
|
|
1319
|
+
if (!(!documents.length && dateField)) return [3 /*break*/, 10];
|
|
1168
1320
|
fallback = resolveAggregateDateFieldFallback(limitedPipeline);
|
|
1169
|
-
if (!fallback) return [3 /*break*/,
|
|
1321
|
+
if (!fallback) return [3 /*break*/, 8];
|
|
1170
1322
|
fallbackMeta.dateField = __assign(__assign({}, fallback), { attempted: true, used: false });
|
|
1171
1323
|
fallbackPipeline = replaceAggregateDateField(limitedPipeline, fallback.from, fallback.to);
|
|
1172
|
-
if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/,
|
|
1324
|
+
if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/, 8];
|
|
1173
1325
|
return [4 /*yield*/, db.collection(collection)
|
|
1174
1326
|
.aggregate(fallbackPipeline, normalizedOptions.aggregateOptions)
|
|
1175
1327
|
.toArray()];
|
|
1176
|
-
case
|
|
1328
|
+
case 7:
|
|
1177
1329
|
fallbackDocs = _e.sent();
|
|
1178
1330
|
if (fallbackDocs.length) {
|
|
1179
1331
|
documents = fallbackDocs;
|
|
1180
1332
|
executedPipeline = fallbackPipeline;
|
|
1181
1333
|
fallbackMeta.dateField.used = true;
|
|
1182
1334
|
}
|
|
1183
|
-
_e.label =
|
|
1184
|
-
case
|
|
1185
|
-
if (!(!documents.length && dateField !== 'createdAt')) return [3 /*break*/,
|
|
1335
|
+
_e.label = 8;
|
|
1336
|
+
case 8:
|
|
1337
|
+
if (!(!documents.length && dateField !== 'createdAt')) return [3 /*break*/, 10];
|
|
1186
1338
|
createdFallback = { from: dateField, to: 'createdAt', attempted: true, used: false };
|
|
1187
1339
|
createdPipeline = replaceAggregateDateField(limitedPipeline, dateField, 'createdAt');
|
|
1188
1340
|
fallbackMeta.dateFieldCreatedAt = createdFallback;
|
|
1189
|
-
if (!!containsForbiddenMongoOperators(createdPipeline)) return [3 /*break*/,
|
|
1341
|
+
if (!!containsForbiddenMongoOperators(createdPipeline)) return [3 /*break*/, 10];
|
|
1190
1342
|
return [4 /*yield*/, db.collection(collection)
|
|
1191
1343
|
.aggregate(createdPipeline, normalizedOptions.aggregateOptions)
|
|
1192
1344
|
.toArray()];
|
|
1193
|
-
case
|
|
1345
|
+
case 9:
|
|
1194
1346
|
createdDocs = _e.sent();
|
|
1195
1347
|
if (createdDocs.length) {
|
|
1196
1348
|
documents = createdDocs;
|
|
1197
1349
|
executedPipeline = createdPipeline;
|
|
1198
1350
|
fallbackMeta.dateFieldCreatedAt.used = true;
|
|
1199
1351
|
}
|
|
1200
|
-
_e.label =
|
|
1201
|
-
case
|
|
1202
|
-
if (!(documents.length <= 1)) return [3 /*break*/,
|
|
1352
|
+
_e.label = 10;
|
|
1353
|
+
case 10:
|
|
1354
|
+
if (!(documents.length <= 1)) return [3 /*break*/, 12];
|
|
1203
1355
|
unwindFallback = resolveAggregateUnwindFallback(executedPipeline);
|
|
1204
|
-
if (!unwindFallback) return [3 /*break*/,
|
|
1356
|
+
if (!unwindFallback) return [3 /*break*/, 12];
|
|
1205
1357
|
fallbackMeta.unwind = { path: unwindFallback.path, attempted: true, used: false };
|
|
1206
1358
|
fallbackPipeline = buildAggregateUnwindFallbackPipeline(executedPipeline, unwindFallback);
|
|
1207
|
-
if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/,
|
|
1359
|
+
if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/, 12];
|
|
1208
1360
|
return [4 /*yield*/, db.collection(collection)
|
|
1209
1361
|
.aggregate(fallbackPipeline, normalizedOptions.aggregateOptions)
|
|
1210
1362
|
.toArray()];
|
|
1211
|
-
case
|
|
1363
|
+
case 11:
|
|
1212
1364
|
fallbackDocs = _e.sent();
|
|
1213
1365
|
if (fallbackDocs.length > documents.length) {
|
|
1214
1366
|
documents = fallbackDocs;
|
|
1215
1367
|
executedPipeline = fallbackPipeline;
|
|
1216
1368
|
fallbackMeta.unwind.used = true;
|
|
1217
1369
|
}
|
|
1218
|
-
_e.label =
|
|
1219
|
-
case
|
|
1370
|
+
_e.label = 12;
|
|
1371
|
+
case 12:
|
|
1220
1372
|
sanitizedDocuments = isSuperAdmin
|
|
1221
1373
|
? documents
|
|
1222
1374
|
: documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
|
|
@@ -1229,6 +1381,11 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
1229
1381
|
return [2 /*return*/, __assign({ documents: sanitizedDocuments, display: display }, (isSuperAdmin ? {
|
|
1230
1382
|
debug: {
|
|
1231
1383
|
collection: collection,
|
|
1384
|
+
collectionRequested: rawCollection,
|
|
1385
|
+
collectionResolved: collection,
|
|
1386
|
+
collectionMatched: collectionResolution.matched,
|
|
1387
|
+
collectionCandidates: collectionResolution.candidates,
|
|
1388
|
+
collectionScore: collectionResolution.score,
|
|
1232
1389
|
database: dbName,
|
|
1233
1390
|
query: scopedQuery,
|
|
1234
1391
|
options: normalizedOptions.aggregateOptions,
|
|
@@ -1299,7 +1456,7 @@ function buildAssistantToolRequest(directive, payload) {
|
|
|
1299
1456
|
return request;
|
|
1300
1457
|
}
|
|
1301
1458
|
function buildAssistantToolResultPayload(directive, toolResponse) {
|
|
1302
|
-
var _a;
|
|
1459
|
+
var _a, _b, _c;
|
|
1303
1460
|
var directivePayload = directive.payload || {};
|
|
1304
1461
|
var documents = Array.isArray(toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.documents) ? toolResponse.documents : [];
|
|
1305
1462
|
var includeIds = ((_a = directivePayload === null || directivePayload === void 0 ? void 0 : directivePayload.options) === null || _a === void 0 ? void 0 : _a.includeIds) === true;
|
|
@@ -1316,17 +1473,22 @@ function buildAssistantToolResultPayload(directive, toolResponse) {
|
|
|
1316
1473
|
});
|
|
1317
1474
|
var total = typeof (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.total) === 'number' ? toolResponse.total : null;
|
|
1318
1475
|
var rowCount = documents.length || trimmedDisplay.rowCount;
|
|
1319
|
-
var
|
|
1476
|
+
var requestedCollection = normalizeOptionalString(directivePayload === null || directivePayload === void 0 ? void 0 : directivePayload.collection);
|
|
1477
|
+
var resolvedCollection = normalizeOptionalString((_b = toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) === null || _b === void 0 ? void 0 : _b.collectionResolved)
|
|
1478
|
+
|| normalizeOptionalString((_c = toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) === null || _c === void 0 ? void 0 : _c.collection)
|
|
1479
|
+
|| requestedCollection
|
|
1480
|
+
|| '';
|
|
1320
1481
|
var result = {
|
|
1321
1482
|
type: directive.type === 'aggregate' ? 'mongo_agg' : 'mongo_read',
|
|
1322
1483
|
input: directivePayload,
|
|
1323
1484
|
output: {
|
|
1324
1485
|
display: trimmedDisplay,
|
|
1325
1486
|
total: total !== null ? total : undefined,
|
|
1326
|
-
collection:
|
|
1487
|
+
collection: resolvedCollection || undefined,
|
|
1327
1488
|
rowCount: rowCount,
|
|
1328
1489
|
columns: trimmedDisplay.columns,
|
|
1329
|
-
truncated: trimmedDisplay.truncated
|
|
1490
|
+
truncated: trimmedDisplay.truncated,
|
|
1491
|
+
debug: (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object' ? toolResponse.debug : undefined
|
|
1330
1492
|
}
|
|
1331
1493
|
};
|
|
1332
1494
|
return {
|
|
@@ -1382,6 +1544,82 @@ function buildAssistantToolFallbackResponse(result) {
|
|
|
1382
1544
|
}
|
|
1383
1545
|
return lines.join('\n').trim();
|
|
1384
1546
|
}
|
|
1547
|
+
function buildAssistantDebugPayload(params) {
|
|
1548
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
1549
|
+
var notes = [];
|
|
1550
|
+
if (params.dataQuestion) {
|
|
1551
|
+
notes.push('Detected a data request; tool call required.');
|
|
1552
|
+
}
|
|
1553
|
+
if (params.directiveSource === 'forced') {
|
|
1554
|
+
notes.push('Assistant response omitted a MONGO_* directive; ran a directive-only pass.');
|
|
1555
|
+
}
|
|
1556
|
+
var directive = params.directive;
|
|
1557
|
+
var directivePayload = (directive === null || directive === void 0 ? void 0 : directive.payload) || {};
|
|
1558
|
+
var rawCollection = normalizeOptionalString(directivePayload === null || directivePayload === void 0 ? void 0 : directivePayload.collection);
|
|
1559
|
+
var debugCollectionRequested = normalizeOptionalString((_a = params.toolResponseDebug) === null || _a === void 0 ? void 0 : _a.collectionRequested);
|
|
1560
|
+
var debugCollectionResolved = normalizeOptionalString((_b = params.toolResponseDebug) === null || _b === void 0 ? void 0 : _b.collectionResolved);
|
|
1561
|
+
var debugCollection = normalizeOptionalString((_c = params.toolResponseDebug) === null || _c === void 0 ? void 0 : _c.collection);
|
|
1562
|
+
var requestedCollection = debugCollectionRequested || rawCollection;
|
|
1563
|
+
var resolvedCollection = debugCollectionResolved || debugCollection || requestedCollection;
|
|
1564
|
+
var matchedCollection = typeof ((_d = params.toolResponseDebug) === null || _d === void 0 ? void 0 : _d.collectionMatched) === 'boolean'
|
|
1565
|
+
? params.toolResponseDebug.collectionMatched
|
|
1566
|
+
: undefined;
|
|
1567
|
+
var candidateCollections = Array.isArray((_e = params.toolResponseDebug) === null || _e === void 0 ? void 0 : _e.collectionCandidates)
|
|
1568
|
+
? params.toolResponseDebug.collectionCandidates.filter(Boolean)
|
|
1569
|
+
: [];
|
|
1570
|
+
if (requestedCollection && resolvedCollection && requestedCollection !== resolvedCollection) {
|
|
1571
|
+
notes.push("Resolved collection \"".concat(requestedCollection, "\" -> \"").concat(resolvedCollection, "\"."));
|
|
1572
|
+
}
|
|
1573
|
+
else if (matchedCollection === false && candidateCollections.length) {
|
|
1574
|
+
notes.push("No direct collection match; candidates: ".concat(candidateCollections.join(', '), "."));
|
|
1575
|
+
}
|
|
1576
|
+
if (((_f = params.toolResult) === null || _f === void 0 ? void 0 : _f.type) === 'mongo_agg') {
|
|
1577
|
+
notes.push('Used aggregation for grouped/breakdown request.');
|
|
1578
|
+
}
|
|
1579
|
+
else if (((_g = params.toolResult) === null || _g === void 0 ? void 0 : _g.type) === 'mongo_read') {
|
|
1580
|
+
notes.push('Used read query for list/count request.');
|
|
1581
|
+
}
|
|
1582
|
+
var fallbackInfo = (_h = params.toolResponseDebug) === null || _h === void 0 ? void 0 : _h.fallbacks;
|
|
1583
|
+
if ((_j = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateField) === null || _j === void 0 ? void 0 : _j.used) {
|
|
1584
|
+
notes.push("Retried with date field fallback ".concat(fallbackInfo.dateField.from, " -> ").concat(fallbackInfo.dateField.to, "."));
|
|
1585
|
+
}
|
|
1586
|
+
if ((_k = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateFieldCreatedAt) === null || _k === void 0 ? void 0 : _k.used) {
|
|
1587
|
+
notes.push("Retried with date field fallback ".concat(fallbackInfo.dateFieldCreatedAt.from, " -> ").concat(fallbackInfo.dateFieldCreatedAt.to, "."));
|
|
1588
|
+
}
|
|
1589
|
+
if ((_l = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.unwind) === null || _l === void 0 ? void 0 : _l.used) {
|
|
1590
|
+
notes.push("Applied unwind fallback on ".concat(fallbackInfo.unwind.path, "."));
|
|
1591
|
+
}
|
|
1592
|
+
if (params.toolError) {
|
|
1593
|
+
var errorMessage = ((_m = params.toolError) === null || _m === void 0 ? void 0 : _m.message) || String(params.toolError || '');
|
|
1594
|
+
if (errorMessage) {
|
|
1595
|
+
notes.push("Tool error: ".concat(errorMessage));
|
|
1596
|
+
}
|
|
1597
|
+
}
|
|
1598
|
+
return {
|
|
1599
|
+
decision: {
|
|
1600
|
+
dataQuestion: params.dataQuestion,
|
|
1601
|
+
directiveSource: params.directiveSource
|
|
1602
|
+
},
|
|
1603
|
+
directive: directive ? {
|
|
1604
|
+
type: directive.type,
|
|
1605
|
+
payload: directivePayload,
|
|
1606
|
+
rawLine: directive.rawLine
|
|
1607
|
+
} : null,
|
|
1608
|
+
collection: resolvedCollection || requestedCollection || undefined,
|
|
1609
|
+
collectionRequested: requestedCollection || undefined,
|
|
1610
|
+
collectionResolved: resolvedCollection || undefined,
|
|
1611
|
+
collectionMatched: matchedCollection,
|
|
1612
|
+
collectionCandidates: candidateCollections.length ? candidateCollections : undefined,
|
|
1613
|
+
collectionScore: typeof ((_o = params.toolResponseDebug) === null || _o === void 0 ? void 0 : _o.collectionScore) === 'number'
|
|
1614
|
+
? params.toolResponseDebug.collectionScore
|
|
1615
|
+
: undefined,
|
|
1616
|
+
query: ((_p = params.toolResponseDebug) === null || _p === void 0 ? void 0 : _p.query) || undefined,
|
|
1617
|
+
pipeline: ((_q = params.toolResponseDebug) === null || _q === void 0 ? void 0 : _q.executedPipeline) || ((_r = params.toolResponseDebug) === null || _r === void 0 ? void 0 : _r.originalPipeline) || undefined,
|
|
1618
|
+
options: ((_s = params.toolResponseDebug) === null || _s === void 0 ? void 0 : _s.options) || undefined,
|
|
1619
|
+
fallbacks: ((_t = params.toolResponseDebug) === null || _t === void 0 ? void 0 : _t.fallbacks) || undefined,
|
|
1620
|
+
notes: notes
|
|
1621
|
+
};
|
|
1622
|
+
}
|
|
1385
1623
|
function buildAssistantToolErrorMessage(error, directive, request) {
|
|
1386
1624
|
var _a, _b;
|
|
1387
1625
|
var rawMessage = normalizeOptionalString(error === null || error === void 0 ? void 0 : error.message) || 'Unable to access data.';
|
|
@@ -2006,7 +2244,18 @@ function normalizeAssistantAggregatePipeline(pipeline) {
|
|
|
2006
2244
|
if (!Array.isArray(pipeline)) {
|
|
2007
2245
|
return [];
|
|
2008
2246
|
}
|
|
2009
|
-
return pipeline
|
|
2247
|
+
return pipeline
|
|
2248
|
+
.filter(function (stage) { return stage && typeof stage === 'object' && !Array.isArray(stage); })
|
|
2249
|
+
.map(function (stage) {
|
|
2250
|
+
var next = __assign({}, stage);
|
|
2251
|
+
if (next.$match && typeof next.$match === 'object') {
|
|
2252
|
+
next.$match = applyAssistantNameRegexToQuery(next.$match);
|
|
2253
|
+
}
|
|
2254
|
+
if (next.$geoNear && typeof next.$geoNear === 'object' && next.$geoNear.query) {
|
|
2255
|
+
next.$geoNear = __assign(__assign({}, next.$geoNear), { query: applyAssistantNameRegexToQuery(next.$geoNear.query) });
|
|
2256
|
+
}
|
|
2257
|
+
return next;
|
|
2258
|
+
});
|
|
2010
2259
|
}
|
|
2011
2260
|
function buildAssistantAggregatePipeline(query, pipeline) {
|
|
2012
2261
|
var _a;
|
|
@@ -2275,10 +2524,302 @@ function normalizeMongoQuery(query) {
|
|
|
2275
2524
|
if (containsForbiddenMongoOperators(normalized)) {
|
|
2276
2525
|
throw new Error('AI assistant mongo read: Query contains restricted operators.');
|
|
2277
2526
|
}
|
|
2278
|
-
return normalized;
|
|
2527
|
+
return applyAssistantNameRegexToQuery(normalized);
|
|
2528
|
+
}
|
|
2529
|
+
function shouldApplyAssistantNameRegex(field) {
|
|
2530
|
+
var normalized = String(field || '').toLowerCase().trim();
|
|
2531
|
+
if (!normalized) {
|
|
2532
|
+
return false;
|
|
2533
|
+
}
|
|
2534
|
+
if (normalized.startsWith('$')) {
|
|
2535
|
+
return false;
|
|
2536
|
+
}
|
|
2537
|
+
if (isAssistantIdField(normalized)) {
|
|
2538
|
+
return false;
|
|
2539
|
+
}
|
|
2540
|
+
if (normalized === 'id' || normalized.endsWith('_id')) {
|
|
2541
|
+
return false;
|
|
2542
|
+
}
|
|
2543
|
+
var tokens = normalized.split(/[^a-z0-9]+/g).filter(Boolean);
|
|
2544
|
+
var targetTokens = new Set(['customer', 'well', 'chemical']);
|
|
2545
|
+
var hasTargetToken = tokens.some(function (token) { return targetTokens.has(token); });
|
|
2546
|
+
if (hasTargetToken) {
|
|
2547
|
+
return true;
|
|
2548
|
+
}
|
|
2549
|
+
if (tokens.includes('name')) {
|
|
2550
|
+
return true;
|
|
2551
|
+
}
|
|
2552
|
+
return /(^|[._-])name$/i.test(normalized);
|
|
2553
|
+
}
|
|
2554
|
+
function escapeRegexValue(value) {
|
|
2555
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
2556
|
+
}
|
|
2557
|
+
function applyAssistantNameRegexToQuery(query) {
|
|
2558
|
+
if (Array.isArray(query)) {
|
|
2559
|
+
return query.map(function (entry) { return applyAssistantNameRegexToQuery(entry); });
|
|
2560
|
+
}
|
|
2561
|
+
if (!query || typeof query !== 'object' || query instanceof Date || query instanceof RegExp || isMongoObjectId(query)) {
|
|
2562
|
+
return query;
|
|
2563
|
+
}
|
|
2564
|
+
var result = {};
|
|
2565
|
+
Object.keys(query).forEach(function (key) {
|
|
2566
|
+
var value = query[key];
|
|
2567
|
+
if (key.startsWith('$')) {
|
|
2568
|
+
result[key] = applyAssistantNameRegexToQuery(value);
|
|
2569
|
+
return;
|
|
2570
|
+
}
|
|
2571
|
+
if (typeof value === 'string' && shouldApplyAssistantNameRegex(key)) {
|
|
2572
|
+
var trimmed = value.trim();
|
|
2573
|
+
result[key] = trimmed ? new RegExp(escapeRegexValue(trimmed), 'i') : value;
|
|
2574
|
+
return;
|
|
2575
|
+
}
|
|
2576
|
+
if (value && typeof value === 'object') {
|
|
2577
|
+
result[key] = applyAssistantNameRegexToQuery(value);
|
|
2578
|
+
return;
|
|
2579
|
+
}
|
|
2580
|
+
result[key] = value;
|
|
2581
|
+
});
|
|
2582
|
+
return result;
|
|
2583
|
+
}
|
|
2584
|
+
function normalizeCollectionKey(value) {
|
|
2585
|
+
return String(value || '').toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
2586
|
+
}
|
|
2587
|
+
function normalizeCollectionToken(token) {
|
|
2588
|
+
var trimmed = token.trim();
|
|
2589
|
+
if (!trimmed) {
|
|
2590
|
+
return [];
|
|
2591
|
+
}
|
|
2592
|
+
var tokens = new Set([trimmed]);
|
|
2593
|
+
if (trimmed.length > 4
|
|
2594
|
+
&& trimmed.endsWith('s')
|
|
2595
|
+
&& !trimmed.endsWith('ss')
|
|
2596
|
+
&& !trimmed.endsWith('us')
|
|
2597
|
+
&& !trimmed.endsWith('is')) {
|
|
2598
|
+
tokens.add(trimmed.slice(0, -1));
|
|
2599
|
+
}
|
|
2600
|
+
return Array.from(tokens);
|
|
2601
|
+
}
|
|
2602
|
+
function tokenizeCollectionText(value) {
|
|
2603
|
+
var rawTokens = String(value || '')
|
|
2604
|
+
.toLowerCase()
|
|
2605
|
+
.split(/[^a-z0-9]+/g)
|
|
2606
|
+
.map(function (token) { return token.trim(); })
|
|
2607
|
+
.filter(Boolean);
|
|
2608
|
+
var tokens = [];
|
|
2609
|
+
rawTokens.forEach(function (token) {
|
|
2610
|
+
normalizeCollectionToken(token).forEach(function (normalized) {
|
|
2611
|
+
if (!AI_ASSISTANT_COLLECTION_STOPWORDS.has(normalized)) {
|
|
2612
|
+
tokens.push(normalized);
|
|
2613
|
+
}
|
|
2614
|
+
});
|
|
2615
|
+
});
|
|
2616
|
+
return Array.from(new Set(tokens));
|
|
2617
|
+
}
|
|
2618
|
+
function listAssistantCollections(db, dbName) {
|
|
2619
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2620
|
+
var cacheKey, cached, now, collections, names, _a;
|
|
2621
|
+
return __generator(this, function (_b) {
|
|
2622
|
+
switch (_b.label) {
|
|
2623
|
+
case 0:
|
|
2624
|
+
cacheKey = normalizeOptionalString(dbName) || 'default';
|
|
2625
|
+
cached = AI_ASSISTANT_COLLECTION_CACHE.get(cacheKey);
|
|
2626
|
+
now = Date.now();
|
|
2627
|
+
if (cached && now - cached.updatedAt < AI_ASSISTANT_COLLECTION_CACHE_TTL_MS) {
|
|
2628
|
+
return [2 /*return*/, cached.names];
|
|
2629
|
+
}
|
|
2630
|
+
_b.label = 1;
|
|
2631
|
+
case 1:
|
|
2632
|
+
_b.trys.push([1, 3, , 4]);
|
|
2633
|
+
return [4 /*yield*/, db.listCollections({}, { nameOnly: true }).toArray()];
|
|
2634
|
+
case 2:
|
|
2635
|
+
collections = _b.sent();
|
|
2636
|
+
names = Array.isArray(collections)
|
|
2637
|
+
? collections.map(function (entry) { return normalizeOptionalString(entry === null || entry === void 0 ? void 0 : entry.name); }).filter(Boolean)
|
|
2638
|
+
: [];
|
|
2639
|
+
AI_ASSISTANT_COLLECTION_CACHE.set(cacheKey, { names: names, updatedAt: now });
|
|
2640
|
+
return [2 /*return*/, names];
|
|
2641
|
+
case 3:
|
|
2642
|
+
_a = _b.sent();
|
|
2643
|
+
return [2 /*return*/, (cached === null || cached === void 0 ? void 0 : cached.names) || []];
|
|
2644
|
+
case 4: return [2 /*return*/];
|
|
2645
|
+
}
|
|
2646
|
+
});
|
|
2647
|
+
});
|
|
2648
|
+
}
|
|
2649
|
+
function scoreCollectionMatch(requestedTokens, candidateName) {
|
|
2650
|
+
if (!requestedTokens.length) {
|
|
2651
|
+
return 0;
|
|
2652
|
+
}
|
|
2653
|
+
var candidateTokens = tokenizeCollectionText(candidateName);
|
|
2654
|
+
if (!candidateTokens.length) {
|
|
2655
|
+
return 0;
|
|
2656
|
+
}
|
|
2657
|
+
var score = 0;
|
|
2658
|
+
requestedTokens.forEach(function (token) {
|
|
2659
|
+
if (candidateTokens.includes(token)) {
|
|
2660
|
+
score += 10;
|
|
2661
|
+
}
|
|
2662
|
+
});
|
|
2663
|
+
var requestedKey = normalizeCollectionKey(requestedTokens.join('-'));
|
|
2664
|
+
var candidateKey = normalizeCollectionKey(candidateName);
|
|
2665
|
+
if (candidateKey === requestedKey && requestedKey) {
|
|
2666
|
+
score += 50;
|
|
2667
|
+
}
|
|
2668
|
+
else if (requestedKey && (candidateKey.includes(requestedKey) || requestedKey.includes(candidateKey))) {
|
|
2669
|
+
score += 20;
|
|
2670
|
+
}
|
|
2671
|
+
return score;
|
|
2672
|
+
}
|
|
2673
|
+
function findBestCollectionMatch(requested, collectionNames) {
|
|
2674
|
+
var requestedTokens = tokenizeCollectionText(requested);
|
|
2675
|
+
if (!requestedTokens.length || !collectionNames.length) {
|
|
2676
|
+
return null;
|
|
2677
|
+
}
|
|
2678
|
+
var best = null;
|
|
2679
|
+
collectionNames.forEach(function (name) {
|
|
2680
|
+
var score = scoreCollectionMatch(requestedTokens, name);
|
|
2681
|
+
if (!best || score > best.score) {
|
|
2682
|
+
best = { name: name, score: score };
|
|
2683
|
+
}
|
|
2684
|
+
});
|
|
2685
|
+
return best;
|
|
2686
|
+
}
|
|
2687
|
+
function resolveAssistantCollectionName(db, dbName, requested) {
|
|
2688
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2689
|
+
var trimmed, collectionNames, best, candidates;
|
|
2690
|
+
return __generator(this, function (_a) {
|
|
2691
|
+
switch (_a.label) {
|
|
2692
|
+
case 0:
|
|
2693
|
+
trimmed = normalizeOptionalString(requested);
|
|
2694
|
+
if (!trimmed) {
|
|
2695
|
+
return [2 /*return*/, { name: '', matched: false, candidates: [], score: 0 }];
|
|
2696
|
+
}
|
|
2697
|
+
return [4 /*yield*/, listAssistantCollections(db, dbName)];
|
|
2698
|
+
case 1:
|
|
2699
|
+
collectionNames = _a.sent();
|
|
2700
|
+
if (collectionNames.includes(trimmed)) {
|
|
2701
|
+
return [2 /*return*/, { name: trimmed, matched: true, candidates: [], score: 100 }];
|
|
2702
|
+
}
|
|
2703
|
+
best = findBestCollectionMatch(trimmed, collectionNames);
|
|
2704
|
+
if (best && best.score >= 20) {
|
|
2705
|
+
return [2 /*return*/, { name: best.name, matched: true, candidates: [], score: best.score }];
|
|
2706
|
+
}
|
|
2707
|
+
candidates = collectionNames
|
|
2708
|
+
.map(function (name) { return ({ name: name, score: scoreCollectionMatch(tokenizeCollectionText(trimmed), name) }); })
|
|
2709
|
+
.filter(function (entry) { return entry.score > 0; })
|
|
2710
|
+
.sort(function (a, b) { return b.score - a.score; })
|
|
2711
|
+
.slice(0, 5)
|
|
2712
|
+
.map(function (entry) { return entry.name; });
|
|
2713
|
+
return [2 /*return*/, { name: trimmed, matched: false, candidates: candidates, score: (best === null || best === void 0 ? void 0 : best.score) || 0 }];
|
|
2714
|
+
}
|
|
2715
|
+
});
|
|
2716
|
+
});
|
|
2717
|
+
}
|
|
2718
|
+
function resolveAssistantCollectionHints(message, dbName, db) {
|
|
2719
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2720
|
+
var text, collectionNames, tokens;
|
|
2721
|
+
return __generator(this, function (_a) {
|
|
2722
|
+
switch (_a.label) {
|
|
2723
|
+
case 0:
|
|
2724
|
+
text = normalizeOptionalString(message);
|
|
2725
|
+
if (!text) {
|
|
2726
|
+
return [2 /*return*/, []];
|
|
2727
|
+
}
|
|
2728
|
+
return [4 /*yield*/, listAssistantCollections(db, dbName)];
|
|
2729
|
+
case 1:
|
|
2730
|
+
collectionNames = _a.sent();
|
|
2731
|
+
if (!collectionNames.length) {
|
|
2732
|
+
return [2 /*return*/, []];
|
|
2733
|
+
}
|
|
2734
|
+
tokens = tokenizeCollectionText(text);
|
|
2735
|
+
if (!tokens.length) {
|
|
2736
|
+
return [2 /*return*/, []];
|
|
2737
|
+
}
|
|
2738
|
+
return [2 /*return*/, collectionNames
|
|
2739
|
+
.map(function (name) { return ({ name: name, score: scoreCollectionMatch(tokens, name) }); })
|
|
2740
|
+
.filter(function (entry) { return entry.score > 0; })
|
|
2741
|
+
.sort(function (a, b) { return b.score - a.score; })
|
|
2742
|
+
.slice(0, 5)
|
|
2743
|
+
.map(function (entry) { return entry.name; })];
|
|
2744
|
+
}
|
|
2745
|
+
});
|
|
2746
|
+
});
|
|
2747
|
+
}
|
|
2748
|
+
function findQueryDateField(query) {
|
|
2749
|
+
var e_1, _a, e_2, _b;
|
|
2750
|
+
if (!query || typeof query !== 'object') {
|
|
2751
|
+
return null;
|
|
2752
|
+
}
|
|
2753
|
+
if (Array.isArray(query)) {
|
|
2754
|
+
try {
|
|
2755
|
+
for (var query_1 = __values(query), query_1_1 = query_1.next(); !query_1_1.done; query_1_1 = query_1.next()) {
|
|
2756
|
+
var entry = query_1_1.value;
|
|
2757
|
+
var found = findQueryDateField(entry);
|
|
2758
|
+
if (found) {
|
|
2759
|
+
return found;
|
|
2760
|
+
}
|
|
2761
|
+
}
|
|
2762
|
+
}
|
|
2763
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
2764
|
+
finally {
|
|
2765
|
+
try {
|
|
2766
|
+
if (query_1_1 && !query_1_1.done && (_a = query_1.return)) _a.call(query_1);
|
|
2767
|
+
}
|
|
2768
|
+
finally { if (e_1) throw e_1.error; }
|
|
2769
|
+
}
|
|
2770
|
+
return null;
|
|
2771
|
+
}
|
|
2772
|
+
try {
|
|
2773
|
+
for (var _c = __values(Object.keys(query)), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
2774
|
+
var key = _d.value;
|
|
2775
|
+
if (key.startsWith('$')) {
|
|
2776
|
+
var found = findQueryDateField(query[key]);
|
|
2777
|
+
if (found) {
|
|
2778
|
+
return found;
|
|
2779
|
+
}
|
|
2780
|
+
continue;
|
|
2781
|
+
}
|
|
2782
|
+
if (AI_ASSISTANT_DATE_FALLBACKS[key]) {
|
|
2783
|
+
return key;
|
|
2784
|
+
}
|
|
2785
|
+
}
|
|
2786
|
+
}
|
|
2787
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
2788
|
+
finally {
|
|
2789
|
+
try {
|
|
2790
|
+
if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
|
|
2791
|
+
}
|
|
2792
|
+
finally { if (e_2) throw e_2.error; }
|
|
2793
|
+
}
|
|
2794
|
+
return null;
|
|
2795
|
+
}
|
|
2796
|
+
function replaceQueryField(query, fromField, toField) {
|
|
2797
|
+
if (Array.isArray(query)) {
|
|
2798
|
+
return query.map(function (entry) { return replaceQueryField(entry, fromField, toField); });
|
|
2799
|
+
}
|
|
2800
|
+
if (!query || typeof query !== 'object' || query instanceof Date) {
|
|
2801
|
+
return query;
|
|
2802
|
+
}
|
|
2803
|
+
var result = {};
|
|
2804
|
+
Object.keys(query).forEach(function (key) {
|
|
2805
|
+
var nextKey = key === fromField ? toField : key;
|
|
2806
|
+
result[nextKey] = replaceQueryField(query[key], fromField, toField);
|
|
2807
|
+
});
|
|
2808
|
+
return result;
|
|
2809
|
+
}
|
|
2810
|
+
function resolveQueryDateFieldFallback(query) {
|
|
2811
|
+
var dateField = findQueryDateField(query);
|
|
2812
|
+
if (!dateField) {
|
|
2813
|
+
return null;
|
|
2814
|
+
}
|
|
2815
|
+
var fallback = AI_ASSISTANT_DATE_FALLBACKS[dateField];
|
|
2816
|
+
if (!fallback) {
|
|
2817
|
+
return null;
|
|
2818
|
+
}
|
|
2819
|
+
return { from: dateField, to: fallback };
|
|
2279
2820
|
}
|
|
2280
2821
|
function containsForbiddenMongoOperators(value) {
|
|
2281
|
-
var
|
|
2822
|
+
var e_3, _a;
|
|
2282
2823
|
if (!value || typeof value !== 'object') {
|
|
2283
2824
|
return false;
|
|
2284
2825
|
}
|
|
@@ -2297,12 +2838,12 @@ function containsForbiddenMongoOperators(value) {
|
|
|
2297
2838
|
}
|
|
2298
2839
|
}
|
|
2299
2840
|
}
|
|
2300
|
-
catch (
|
|
2841
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
2301
2842
|
finally {
|
|
2302
2843
|
try {
|
|
2303
2844
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
2304
2845
|
}
|
|
2305
|
-
finally { if (
|
|
2846
|
+
finally { if (e_3) throw e_3.error; }
|
|
2306
2847
|
}
|
|
2307
2848
|
return false;
|
|
2308
2849
|
}
|
|
@@ -2465,6 +3006,20 @@ function resolveCodexModel() {
|
|
|
2465
3006
|
|| process.env.AI_DASHBOARD_CODEX_MODEL);
|
|
2466
3007
|
return raw || DEFAULT_CODEX_MODEL;
|
|
2467
3008
|
}
|
|
3009
|
+
function resolveCodexThoughtLevel() {
|
|
3010
|
+
var config = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
|
|
3011
|
+
var raw = normalizeOptionalString(config['AI_ASSISTANT_CODEX_THOUGHT_LEVEL']
|
|
3012
|
+
|| process.env.AI_ASSISTANT_CODEX_THOUGHT_LEVEL
|
|
3013
|
+
|| config['AI_TERMINAL_CODEX_THOUGHT_LEVEL']
|
|
3014
|
+
|| process.env.AI_TERMINAL_CODEX_THOUGHT_LEVEL
|
|
3015
|
+
|| config['AI_DASHBOARD_CODEX_THOUGHT_LEVEL']
|
|
3016
|
+
|| process.env.AI_DASHBOARD_CODEX_THOUGHT_LEVEL);
|
|
3017
|
+
var normalized = (raw || '').trim().toLowerCase();
|
|
3018
|
+
if (normalized === 'minimal' || normalized === 'low' || normalized === 'medium' || normalized === 'high' || normalized === 'xhigh') {
|
|
3019
|
+
return normalized;
|
|
3020
|
+
}
|
|
3021
|
+
return 'low';
|
|
3022
|
+
}
|
|
2468
3023
|
function resolveCodexSettings() {
|
|
2469
3024
|
var serverConfig = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
|
|
2470
3025
|
var apiKey = (serverConfig['OPENAI_API_KEY'] || process.env.OPENAI_API_KEY || '').trim();
|
|
@@ -2522,8 +3077,8 @@ function applyCodexStreamStatusHandler(runOptions, streamStatusHandler) {
|
|
|
2522
3077
|
}
|
|
2523
3078
|
function waitForCodexWorkerMessage(worker, streamStatusHandler) {
|
|
2524
3079
|
return __awaiter(this, void 0, void 0, function () {
|
|
2525
|
-
var _a, _b, _c, _d, message, payload, status_1,
|
|
2526
|
-
var _e,
|
|
3080
|
+
var _a, _b, _c, _d, message, payload, status_1, e_4_1;
|
|
3081
|
+
var _e, e_4, _f, _g;
|
|
2527
3082
|
return __generator(this, function (_h) {
|
|
2528
3083
|
switch (_h.label) {
|
|
2529
3084
|
case 0:
|
|
@@ -2550,8 +3105,8 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
|
|
|
2550
3105
|
return [3 /*break*/, 1];
|
|
2551
3106
|
case 4: return [3 /*break*/, 11];
|
|
2552
3107
|
case 5:
|
|
2553
|
-
|
|
2554
|
-
|
|
3108
|
+
e_4_1 = _h.sent();
|
|
3109
|
+
e_4 = { error: e_4_1 };
|
|
2555
3110
|
return [3 /*break*/, 11];
|
|
2556
3111
|
case 6:
|
|
2557
3112
|
_h.trys.push([6, , 9, 10]);
|
|
@@ -2562,7 +3117,7 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
|
|
|
2562
3117
|
_h.label = 8;
|
|
2563
3118
|
case 8: return [3 /*break*/, 10];
|
|
2564
3119
|
case 9:
|
|
2565
|
-
if (
|
|
3120
|
+
if (e_4) throw e_4.error;
|
|
2566
3121
|
return [7 /*endfinally*/];
|
|
2567
3122
|
case 10: return [7 /*endfinally*/];
|
|
2568
3123
|
case 11: throw new CodexWorkerBootstrapError('Codex worker exited before completing.');
|
|
@@ -2838,6 +3393,43 @@ function resolveAssistantWorkspaceRoot() {
|
|
|
2838
3393
|
});
|
|
2839
3394
|
});
|
|
2840
3395
|
}
|
|
3396
|
+
function isAssistantDataQuestion(message) {
|
|
3397
|
+
var text = normalizeOptionalString(message).toLowerCase();
|
|
3398
|
+
if (!text) {
|
|
3399
|
+
return false;
|
|
3400
|
+
}
|
|
3401
|
+
var patterns = [
|
|
3402
|
+
/\bshow\b/,
|
|
3403
|
+
/\blist\b/,
|
|
3404
|
+
/\bhow many\b/,
|
|
3405
|
+
/\bcount\b/,
|
|
3406
|
+
/\btotal\b/,
|
|
3407
|
+
/\bnumber of\b/,
|
|
3408
|
+
/\blast\b/,
|
|
3409
|
+
/\brecent\b/,
|
|
3410
|
+
/\bthis week\b/,
|
|
3411
|
+
/\blast month\b/,
|
|
3412
|
+
/\boverdue\b/,
|
|
3413
|
+
/\bopen\b/,
|
|
3414
|
+
/\bclosed\b/,
|
|
3415
|
+
/\bcompleted\b/,
|
|
3416
|
+
/\bmissing\b/,
|
|
3417
|
+
/\bgroup(ed)? by\b/,
|
|
3418
|
+
/\bbreakdown\b/,
|
|
3419
|
+
/\bper day\b/,
|
|
3420
|
+
/\bper week\b/,
|
|
3421
|
+
/\bper month\b/
|
|
3422
|
+
];
|
|
3423
|
+
return patterns.some(function (pattern) { return pattern.test(text); });
|
|
3424
|
+
}
|
|
3425
|
+
function buildAssistantCodexDirectivePrompt(message, attachmentText, historyText, contextText) {
|
|
3426
|
+
var trimmedContext = normalizeOptionalString(contextText);
|
|
3427
|
+
var contextBlock = trimmedContext ? "\n\nContext:\n".concat(trimmedContext) : '';
|
|
3428
|
+
var trimmedHistory = normalizeOptionalString(historyText);
|
|
3429
|
+
var historyBlock = trimmedHistory ? "\n\nConversation so far:\n".concat(trimmedHistory) : '';
|
|
3430
|
+
var instruction = '\n\nInstruction:\nReturn ONLY a single MONGO_READ or MONGO_AGG directive line. Do not include any other text.';
|
|
3431
|
+
return "System:\n".concat(AI_ASSISTANT_SYSTEM_PROMPT).concat(contextBlock).concat(historyBlock, "\n\nUser:\n").concat(message).concat(attachmentText || '').concat(instruction).trim();
|
|
3432
|
+
}
|
|
2841
3433
|
function buildAssistantCodexPrompt(message, attachmentText, historyText, contextText) {
|
|
2842
3434
|
var trimmedContext = normalizeOptionalString(contextText);
|
|
2843
3435
|
var contextBlock = trimmedContext ? "\n\nContext:\n".concat(trimmedContext) : '';
|
|
@@ -2871,6 +3463,12 @@ function buildAssistantContext(input, userContext) {
|
|
|
2871
3463
|
if (contextRoute) {
|
|
2872
3464
|
lines.push("Current page route: ".concat(contextRoute));
|
|
2873
3465
|
}
|
|
3466
|
+
var collectionHints = Array.isArray(userContext === null || userContext === void 0 ? void 0 : userContext.collectionHints)
|
|
3467
|
+
? userContext === null || userContext === void 0 ? void 0 : userContext.collectionHints.filter(Boolean)
|
|
3468
|
+
: [];
|
|
3469
|
+
if (collectionHints.length) {
|
|
3470
|
+
lines.push("Collection hints: ".concat(collectionHints.join(', ')));
|
|
3471
|
+
}
|
|
2874
3472
|
var mongoDb = normalizeOptionalString((_c = input === null || input === void 0 ? void 0 : input.mongo) === null || _c === void 0 ? void 0 : _c.database);
|
|
2875
3473
|
var mongoDbs = Array.isArray((_d = input === null || input === void 0 ? void 0 : input.mongo) === null || _d === void 0 ? void 0 : _d.databases)
|
|
2876
3474
|
? input.mongo.databases.map(function (value) { return normalizeOptionalString(value); }).filter(Boolean)
|
|
@@ -2901,7 +3499,7 @@ function normalizeRouteMatchKey(value) {
|
|
|
2901
3499
|
return normalizeRouteKey(value).toLowerCase();
|
|
2902
3500
|
}
|
|
2903
3501
|
function buildClientRouteIndex() {
|
|
2904
|
-
var
|
|
3502
|
+
var e_5, _a;
|
|
2905
3503
|
var _b;
|
|
2906
3504
|
var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
|
|
2907
3505
|
var set = new Set();
|
|
@@ -2920,12 +3518,12 @@ function buildClientRouteIndex() {
|
|
|
2920
3518
|
}
|
|
2921
3519
|
}
|
|
2922
3520
|
}
|
|
2923
|
-
catch (
|
|
3521
|
+
catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
|
2924
3522
|
finally {
|
|
2925
3523
|
try {
|
|
2926
3524
|
if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
|
|
2927
3525
|
}
|
|
2928
|
-
finally { if (
|
|
3526
|
+
finally { if (e_5) throw e_5.error; }
|
|
2929
3527
|
}
|
|
2930
3528
|
return { set: set, map: map, size: routes.length };
|
|
2931
3529
|
}
|
|
@@ -3045,10 +3643,13 @@ function sanitizeAssistantResponse(value) {
|
|
|
3045
3643
|
if (!cleaned) {
|
|
3046
3644
|
return 'I can’t share code, but I can point you to files or explain behavior at a high level.';
|
|
3047
3645
|
}
|
|
3048
|
-
|
|
3646
|
+
var normalizedCurrency = cleaned.replace(/\bUSD\s*([0-9][0-9,]*(?:\.[0-9]+)?)/g, function (_match, amount) {
|
|
3647
|
+
return "$".concat(amount);
|
|
3648
|
+
});
|
|
3649
|
+
return normalizeAssistantRoutes(normalizedCurrency);
|
|
3049
3650
|
}
|
|
3050
3651
|
function evaluateAssistantGuardrails(message) {
|
|
3051
|
-
var
|
|
3652
|
+
var e_6, _a;
|
|
3052
3653
|
var normalized = String(message || '').toLowerCase();
|
|
3053
3654
|
var patterns = [
|
|
3054
3655
|
{
|
|
@@ -3094,12 +3695,12 @@ function evaluateAssistantGuardrails(message) {
|
|
|
3094
3695
|
}
|
|
3095
3696
|
}
|
|
3096
3697
|
}
|
|
3097
|
-
catch (
|
|
3698
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
3098
3699
|
finally {
|
|
3099
3700
|
try {
|
|
3100
3701
|
if (patterns_1_1 && !patterns_1_1.done && (_a = patterns_1.return)) _a.call(patterns_1);
|
|
3101
3702
|
}
|
|
3102
|
-
finally { if (
|
|
3703
|
+
finally { if (e_6) throw e_6.error; }
|
|
3103
3704
|
}
|
|
3104
3705
|
return null;
|
|
3105
3706
|
}
|
|
@@ -3263,8 +3864,8 @@ function handleCodexUpload(id_conversation, file_name, content_base64, size, con
|
|
|
3263
3864
|
}
|
|
3264
3865
|
function readAttachmentContents(attachments) {
|
|
3265
3866
|
return __awaiter(this, void 0, void 0, function () {
|
|
3266
|
-
var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a,
|
|
3267
|
-
var
|
|
3867
|
+
var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_7_1;
|
|
3868
|
+
var e_7, _b;
|
|
3268
3869
|
return __generator(this, function (_c) {
|
|
3269
3870
|
switch (_c.label) {
|
|
3270
3871
|
case 0:
|
|
@@ -3343,14 +3944,14 @@ function readAttachmentContents(attachments) {
|
|
|
3343
3944
|
return [3 /*break*/, 2];
|
|
3344
3945
|
case 10: return [3 /*break*/, 13];
|
|
3345
3946
|
case 11:
|
|
3346
|
-
|
|
3347
|
-
|
|
3947
|
+
e_7_1 = _c.sent();
|
|
3948
|
+
e_7 = { error: e_7_1 };
|
|
3348
3949
|
return [3 /*break*/, 13];
|
|
3349
3950
|
case 12:
|
|
3350
3951
|
try {
|
|
3351
3952
|
if (attachments_1_1 && !attachments_1_1.done && (_b = attachments_1.return)) _b.call(attachments_1);
|
|
3352
3953
|
}
|
|
3353
|
-
finally { if (
|
|
3954
|
+
finally { if (e_7) throw e_7.error; }
|
|
3354
3955
|
return [7 /*endfinally*/];
|
|
3355
3956
|
case 13: return [2 /*return*/, {
|
|
3356
3957
|
promptText: chunks.length ? "\n\nAttachments:\n".concat(chunks.join('\n\n')) : '',
|
|
@@ -3527,7 +4128,7 @@ function estimateUsage(messages, responseText, model) {
|
|
|
3527
4128
|
};
|
|
3528
4129
|
}
|
|
3529
4130
|
function evaluateGuardrails(message) {
|
|
3530
|
-
var
|
|
4131
|
+
var e_8, _a;
|
|
3531
4132
|
var normalized = String(message || '').toLowerCase();
|
|
3532
4133
|
var patterns = [
|
|
3533
4134
|
{ pattern: /\b(source\s*code|full\s*code|entire\s*code|repo\s*dump|repository|git\s*clone)\b/i, reason: 'Code access is restricted.' },
|
|
@@ -3549,12 +4150,12 @@ function evaluateGuardrails(message) {
|
|
|
3549
4150
|
}
|
|
3550
4151
|
}
|
|
3551
4152
|
}
|
|
3552
|
-
catch (
|
|
4153
|
+
catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
|
3553
4154
|
finally {
|
|
3554
4155
|
try {
|
|
3555
4156
|
if (patterns_2_1 && !patterns_2_1.done && (_a = patterns_2.return)) _a.call(patterns_2);
|
|
3556
4157
|
}
|
|
3557
|
-
finally { if (
|
|
4158
|
+
finally { if (e_8) throw e_8.error; }
|
|
3558
4159
|
}
|
|
3559
4160
|
return null;
|
|
3560
4161
|
}
|