@resolveio/server-lib 20.15.3 → 20.15.5
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 +959 -164
- 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;
|
|
@@ -144,6 +144,7 @@ var AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS = 20;
|
|
|
144
144
|
var AI_ASSISTANT_DISPLAY_STRING_LIMIT = 160;
|
|
145
145
|
var AI_ASSISTANT_PROGRESS_PLACEHOLDER = 'Thinking...';
|
|
146
146
|
var AI_ASSISTANT_PROGRESS_TICK_MS = 5000;
|
|
147
|
+
var AI_ASSISTANT_READ_PREFERENCE = 'secondary';
|
|
147
148
|
var AI_ASSISTANT_PROGRESS_TICKS = [
|
|
148
149
|
'Drafting response'
|
|
149
150
|
];
|
|
@@ -199,6 +200,51 @@ var AI_ASSISTANT_SENSITIVE_FIELDS = [
|
|
|
199
200
|
'roles'
|
|
200
201
|
];
|
|
201
202
|
var AI_ASSISTANT_CLIENT_SCOPE_CACHE = new Map();
|
|
203
|
+
var AI_ASSISTANT_COLLECTION_CACHE = new Map();
|
|
204
|
+
var AI_ASSISTANT_COLLECTION_CACHE_TTL_MS = 5 * 60 * 1000;
|
|
205
|
+
var AI_ASSISTANT_COLLECTION_STOPWORDS = new Set([
|
|
206
|
+
'the',
|
|
207
|
+
'a',
|
|
208
|
+
'an',
|
|
209
|
+
'of',
|
|
210
|
+
'for',
|
|
211
|
+
'by',
|
|
212
|
+
'with',
|
|
213
|
+
'and',
|
|
214
|
+
'or',
|
|
215
|
+
'to',
|
|
216
|
+
'from',
|
|
217
|
+
'in',
|
|
218
|
+
'on',
|
|
219
|
+
'at',
|
|
220
|
+
'last',
|
|
221
|
+
'recent',
|
|
222
|
+
'today',
|
|
223
|
+
'week',
|
|
224
|
+
'month',
|
|
225
|
+
'year',
|
|
226
|
+
'this',
|
|
227
|
+
'that',
|
|
228
|
+
'these',
|
|
229
|
+
'those',
|
|
230
|
+
'show',
|
|
231
|
+
'list',
|
|
232
|
+
'get',
|
|
233
|
+
'give',
|
|
234
|
+
'how',
|
|
235
|
+
'many',
|
|
236
|
+
'count',
|
|
237
|
+
'total',
|
|
238
|
+
'breakdown',
|
|
239
|
+
'group',
|
|
240
|
+
'grouped',
|
|
241
|
+
'per',
|
|
242
|
+
'open',
|
|
243
|
+
'closed',
|
|
244
|
+
'completed',
|
|
245
|
+
'missing',
|
|
246
|
+
'overdue'
|
|
247
|
+
]);
|
|
202
248
|
var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
203
249
|
'You are the ResolveIO in-app AI assistant running with read-only access to the codebase.',
|
|
204
250
|
'Core rules:',
|
|
@@ -209,11 +255,16 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
209
255
|
'- 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
256
|
'- Do not assist with hacking, bypassing security, or abuse.',
|
|
211
257
|
'Accuracy & tools:',
|
|
258
|
+
'- 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.',
|
|
259
|
+
'- Map user wording to internal collections/fields yourself. Do not ask for property names unless required to run a query.',
|
|
212
260
|
'- 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
261
|
'- Prefer running a small Mongo read over asking multiple questions.',
|
|
262
|
+
'- For any data request (counts, lists, breakdowns, recent/last items), you MUST run a MONGO_READ or MONGO_AGG before answering.',
|
|
214
263
|
'- Ask at most one clarifying question only when required to run a query or resolve missing details.',
|
|
215
264
|
'- 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.',
|
|
265
|
+
'- 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
266
|
'- Use the codebase context to choose correct collections/fields/workflows and use MONGO_READ/MONGO_AGG to answer with real data when needed.',
|
|
267
|
+
'- Assume a relevant collection exists; if verification reads return zero data, report no data found instead of interrogating the user.',
|
|
217
268
|
'- For direct questions, answer first. Ask a single follow-up only if required to proceed.',
|
|
218
269
|
'Data Presentation:',
|
|
219
270
|
'- Output plain Markdown (NO triple backticks).',
|
|
@@ -224,6 +275,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
224
275
|
'- 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
276
|
'- Rename `createdAt` to `Created At` and `updatedAt` to `Updated At` in tables.',
|
|
226
277
|
'Response style:',
|
|
278
|
+
'- Respond in English only. Do not include non-English text or characters unless required for JSON, links, or tool directives.',
|
|
227
279
|
'- Keep responses concise: answer first, then 3-8 bullets, then a table when data is involved.',
|
|
228
280
|
'- Prefer high-level explanations and point to routes instead of code. Only mention file paths if explicitly requested.',
|
|
229
281
|
'- 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.',
|
|
@@ -256,12 +308,14 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
256
308
|
'- Only request data when the user has permission for that module; invoice data requires invoice view access.',
|
|
257
309
|
'- If the user lacks permission, answer without data and explain how to view it in the app or request access.',
|
|
258
310
|
'- For simple counts or time-range totals, use MONGO_READ (includeTotal). For breakdowns, rankings, or sums grouped by a field, use MONGO_AGG.',
|
|
311
|
+
'- For completion metrics (ex: "completed per day"), filter by completed status when applicable and use completion date fields; if completion dates are missing, fall back to createdAt/date_created and note the fallback.',
|
|
259
312
|
'- 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.',
|
|
260
313
|
'- For creation-date questions when both date_created and createdAt exist, match both with $or so results are not missed.',
|
|
261
314
|
'- When grouping by fields that can be arrays (drivers, deliveries, routes, chemicals), $unwind first and group by both id and name when available.',
|
|
262
315
|
'- Use MONGO_READ/MONGO_AGG only to produce summaries/snapshots/health checks (not raw dumps) when permitted.',
|
|
263
316
|
'- If the user explicitly asks for IDs, set options.includeIds: true.',
|
|
264
|
-
'-
|
|
317
|
+
'- 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.',
|
|
318
|
+
'- Keep responses concise and use the configured reasoning effort level (default low).'
|
|
265
319
|
].join('\n');
|
|
266
320
|
var AI_FORM_PATCH_SYSTEM_PROMPT = [
|
|
267
321
|
'You are the ResolveIO form patch assistant.',
|
|
@@ -800,10 +854,10 @@ function executeAiFormPatch(payload, context) {
|
|
|
800
854
|
}
|
|
801
855
|
function executeAiAssistantCodexRun(payload, context) {
|
|
802
856
|
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 (
|
|
857
|
+
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;
|
|
858
|
+
var _f, _g, _h;
|
|
859
|
+
return __generator(this, function (_j) {
|
|
860
|
+
switch (_j.label) {
|
|
807
861
|
case 0:
|
|
808
862
|
input = payload || {};
|
|
809
863
|
message = normalizeOptionalString(input.message);
|
|
@@ -818,7 +872,7 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
818
872
|
if (!(guardrail === null || guardrail === void 0 ? void 0 : guardrail.blocked)) return [3 /*break*/, 5];
|
|
819
873
|
return [4 /*yield*/, ensureConversation(input, 'codex')];
|
|
820
874
|
case 1:
|
|
821
|
-
conversation_2 =
|
|
875
|
+
conversation_2 = _j.sent();
|
|
822
876
|
now_2 = new Date();
|
|
823
877
|
userMsg = {
|
|
824
878
|
id_conversation: conversation_2._id,
|
|
@@ -838,13 +892,13 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
838
892
|
};
|
|
839
893
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userMsg)];
|
|
840
894
|
case 2:
|
|
841
|
-
|
|
895
|
+
_j.sent();
|
|
842
896
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(assistantMsg)];
|
|
843
897
|
case 3:
|
|
844
|
-
|
|
898
|
+
_j.sent();
|
|
845
899
|
return [4 /*yield*/, touchConversation(conversation_2._id, now_2)];
|
|
846
900
|
case 4:
|
|
847
|
-
|
|
901
|
+
_j.sent();
|
|
848
902
|
return [2 /*return*/, {
|
|
849
903
|
conversation: conversation_2,
|
|
850
904
|
message: assistantMsg,
|
|
@@ -852,27 +906,27 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
852
906
|
}];
|
|
853
907
|
case 5: return [4 /*yield*/, user_collection_1.Users.findById(context === null || context === void 0 ? void 0 : context.id_user)];
|
|
854
908
|
case 6:
|
|
855
|
-
user =
|
|
856
|
-
isSuperAdmin = !!((
|
|
909
|
+
user = _j.sent();
|
|
910
|
+
isSuperAdmin = !!((_f = user === null || user === void 0 ? void 0 : user.roles) === null || _f === void 0 ? void 0 : _f.super_admin);
|
|
857
911
|
hasInvoiceAccess = userHasInvoiceAccess(user);
|
|
858
|
-
customerId = normalizeOptionalString((
|
|
912
|
+
customerId = normalizeOptionalString((_g = user === null || user === void 0 ? void 0 : user.other) === null || _g === void 0 ? void 0 : _g.id_customer);
|
|
859
913
|
return [4 /*yield*/, ensureConversation(input, 'codex')];
|
|
860
914
|
case 7:
|
|
861
|
-
conversation =
|
|
915
|
+
conversation = _j.sent();
|
|
862
916
|
now = new Date();
|
|
863
917
|
attachments = Array.isArray(input.attachments) ? input.attachments : [];
|
|
864
918
|
return [4 /*yield*/, readAttachmentContents(attachments)];
|
|
865
919
|
case 8:
|
|
866
|
-
attachmentData =
|
|
920
|
+
attachmentData = _j.sent();
|
|
867
921
|
historyLimit = normalizeHistoryLimit(input.max_history);
|
|
868
922
|
if (!(historyLimit > 0)) return [3 /*break*/, 10];
|
|
869
923
|
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
924
|
case 9:
|
|
871
|
-
_a =
|
|
925
|
+
_a = _j.sent();
|
|
872
926
|
return [3 /*break*/, 11];
|
|
873
927
|
case 10:
|
|
874
928
|
_a = [];
|
|
875
|
-
|
|
929
|
+
_j.label = 11;
|
|
876
930
|
case 11:
|
|
877
931
|
history = _a;
|
|
878
932
|
historyLines = [];
|
|
@@ -883,11 +937,35 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
883
937
|
historyLines.push("".concat(role, ": ").concat(content));
|
|
884
938
|
}
|
|
885
939
|
});
|
|
886
|
-
|
|
940
|
+
collectionHints = [];
|
|
941
|
+
_j.label = 12;
|
|
942
|
+
case 12:
|
|
943
|
+
_j.trys.push([12, 14, , 15]);
|
|
944
|
+
dbName = resolveAssistantDatabaseName(undefined, input.mongo);
|
|
945
|
+
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
946
|
+
hintText = [
|
|
947
|
+
message,
|
|
948
|
+
normalizeOptionalString((_h = input === null || input === void 0 ? void 0 : input.context) === null || _h === void 0 ? void 0 : _h.route)
|
|
949
|
+
].filter(Boolean).join(' ');
|
|
950
|
+
return [4 /*yield*/, resolveAssistantCollectionHints(hintText, dbName, db)];
|
|
951
|
+
case 13:
|
|
952
|
+
collectionHints = _j.sent();
|
|
953
|
+
return [3 /*break*/, 15];
|
|
954
|
+
case 14:
|
|
955
|
+
_b = _j.sent();
|
|
956
|
+
collectionHints = [];
|
|
957
|
+
return [3 /*break*/, 15];
|
|
958
|
+
case 15:
|
|
959
|
+
assistantContext = buildAssistantContext(input, {
|
|
960
|
+
isSuperAdmin: isSuperAdmin,
|
|
961
|
+
hasInvoiceAccess: hasInvoiceAccess,
|
|
962
|
+
customerId: customerId,
|
|
963
|
+
collectionHints: collectionHints
|
|
964
|
+
});
|
|
887
965
|
prompt = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
|
|
888
966
|
return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
|
|
889
|
-
case
|
|
890
|
-
workspaceRoot =
|
|
967
|
+
case 16:
|
|
968
|
+
workspaceRoot = _j.sent();
|
|
891
969
|
codexConfig = resolveCodexSettings();
|
|
892
970
|
runOptions = {
|
|
893
971
|
timeoutMs: resolveCodexTimeoutMs(),
|
|
@@ -895,7 +973,7 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
895
973
|
workingDirectory: workspaceRoot,
|
|
896
974
|
sandboxMode: 'read-only',
|
|
897
975
|
skipGitRepoCheck: true,
|
|
898
|
-
modelReasoningEffort:
|
|
976
|
+
modelReasoningEffort: resolveCodexThoughtLevel(),
|
|
899
977
|
networkAccessEnabled: false,
|
|
900
978
|
webSearchMode: 'disabled',
|
|
901
979
|
webSearchEnabled: false,
|
|
@@ -921,83 +999,128 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
921
999
|
updatedAt: now
|
|
922
1000
|
};
|
|
923
1001
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userDoc)];
|
|
924
|
-
case
|
|
925
|
-
|
|
1002
|
+
case 17:
|
|
1003
|
+
_j.sent();
|
|
926
1004
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(assistantDoc)];
|
|
927
|
-
case
|
|
928
|
-
insertResult =
|
|
1005
|
+
case 18:
|
|
1006
|
+
insertResult = _j.sent();
|
|
929
1007
|
assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
|
|
930
1008
|
progressTracker = createAssistantProgressTracker(assistantMessageId, initialProgress);
|
|
931
1009
|
streamProgress = createAssistantStreamProgressHandler(progressTracker);
|
|
932
1010
|
assistantContent = '';
|
|
933
1011
|
toolResult = null;
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
1012
|
+
assistantDebug = null;
|
|
1013
|
+
directiveSource = 'none';
|
|
1014
|
+
dataQuestion = isAssistantDataQuestion(message);
|
|
1015
|
+
lastDirective = null;
|
|
1016
|
+
toolResponseDebug = null;
|
|
1017
|
+
toolError = null;
|
|
1018
|
+
_j.label = 19;
|
|
1019
|
+
case 19:
|
|
1020
|
+
_j.trys.push([19, 38, 39, 40]);
|
|
937
1021
|
return [4 /*yield*/, runCodexInWorkerThread(prompt, runOptions, codexConfig, streamProgress)];
|
|
938
|
-
case
|
|
939
|
-
responseText =
|
|
1022
|
+
case 20:
|
|
1023
|
+
responseText = _j.sent();
|
|
940
1024
|
directive = extractAssistantMongoDirective(responseText);
|
|
941
|
-
|
|
1025
|
+
directiveSourceText = responseText;
|
|
1026
|
+
if (directive) {
|
|
1027
|
+
directiveSource = 'model';
|
|
1028
|
+
lastDirective = directive;
|
|
1029
|
+
}
|
|
1030
|
+
if (!(!directive && dataQuestion)) return [3 /*break*/, 24];
|
|
1031
|
+
directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
|
|
1032
|
+
_j.label = 21;
|
|
1033
|
+
case 21:
|
|
1034
|
+
_j.trys.push([21, 23, , 24]);
|
|
1035
|
+
return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
|
|
1036
|
+
case 22:
|
|
1037
|
+
directiveText = _j.sent();
|
|
1038
|
+
forcedDirective = extractAssistantMongoDirective(directiveText);
|
|
1039
|
+
if (forcedDirective) {
|
|
1040
|
+
directive = forcedDirective;
|
|
1041
|
+
directiveSourceText = directiveText;
|
|
1042
|
+
directiveSource = 'forced';
|
|
1043
|
+
lastDirective = forcedDirective;
|
|
1044
|
+
}
|
|
1045
|
+
return [3 /*break*/, 24];
|
|
1046
|
+
case 23:
|
|
1047
|
+
_c = _j.sent();
|
|
1048
|
+
return [3 /*break*/, 24];
|
|
1049
|
+
case 24:
|
|
1050
|
+
cleanedResponseText = (directive === null || directive === void 0 ? void 0 : directive.cleaned) || directiveSourceText;
|
|
942
1051
|
assistantContent = sanitizeAssistantResponse(cleanedResponseText);
|
|
943
|
-
if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/,
|
|
1052
|
+
if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 36];
|
|
944
1053
|
toolRequest = buildAssistantToolRequest(directive, input);
|
|
945
1054
|
progressTracker.push('Looking up Data');
|
|
946
|
-
|
|
947
|
-
case
|
|
948
|
-
|
|
949
|
-
if (!(directive.type === 'aggregate')) return [3 /*break*/,
|
|
1055
|
+
_j.label = 25;
|
|
1056
|
+
case 25:
|
|
1057
|
+
_j.trys.push([25, 34, , 35]);
|
|
1058
|
+
if (!(directive.type === 'aggregate')) return [3 /*break*/, 27];
|
|
950
1059
|
return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
|
|
951
|
-
case
|
|
952
|
-
|
|
953
|
-
return [3 /*break*/,
|
|
954
|
-
case
|
|
955
|
-
case
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
case
|
|
959
|
-
toolResponse =
|
|
1060
|
+
case 26:
|
|
1061
|
+
_d = _j.sent();
|
|
1062
|
+
return [3 /*break*/, 29];
|
|
1063
|
+
case 27: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
|
|
1064
|
+
case 28:
|
|
1065
|
+
_d = _j.sent();
|
|
1066
|
+
_j.label = 29;
|
|
1067
|
+
case 29:
|
|
1068
|
+
toolResponse = _d;
|
|
1069
|
+
toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
|
|
1070
|
+
? toolResponse.debug
|
|
1071
|
+
: null;
|
|
960
1072
|
toolPayload = buildAssistantToolResultPayload(directive, toolResponse);
|
|
961
1073
|
toolResult = toolPayload.result;
|
|
962
1074
|
progressTracker.push('Drafting response');
|
|
963
1075
|
followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
|
|
964
|
-
|
|
965
|
-
case
|
|
966
|
-
|
|
1076
|
+
_j.label = 30;
|
|
1077
|
+
case 30:
|
|
1078
|
+
_j.trys.push([30, 32, , 33]);
|
|
967
1079
|
return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
|
|
968
|
-
case
|
|
969
|
-
followupText =
|
|
1080
|
+
case 31:
|
|
1081
|
+
followupText = _j.sent();
|
|
970
1082
|
assistantContent = sanitizeAssistantResponse(followupText);
|
|
971
|
-
return [3 /*break*/,
|
|
972
|
-
case
|
|
973
|
-
|
|
1083
|
+
return [3 /*break*/, 33];
|
|
1084
|
+
case 32:
|
|
1085
|
+
_e = _j.sent();
|
|
974
1086
|
assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
|
|
975
|
-
return [3 /*break*/,
|
|
976
|
-
case
|
|
977
|
-
case
|
|
978
|
-
error_1 =
|
|
1087
|
+
return [3 /*break*/, 33];
|
|
1088
|
+
case 33: return [3 /*break*/, 35];
|
|
1089
|
+
case 34:
|
|
1090
|
+
error_1 = _j.sent();
|
|
979
1091
|
assistantContent = buildAssistantToolErrorMessage(error_1, directive, toolRequest);
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
case
|
|
1092
|
+
toolError = error_1;
|
|
1093
|
+
return [3 /*break*/, 35];
|
|
1094
|
+
case 35: return [3 /*break*/, 37];
|
|
1095
|
+
case 36:
|
|
983
1096
|
progressTracker.push('Drafting response');
|
|
984
|
-
|
|
985
|
-
case
|
|
986
|
-
case
|
|
987
|
-
error_2 =
|
|
1097
|
+
_j.label = 37;
|
|
1098
|
+
case 37: return [3 /*break*/, 40];
|
|
1099
|
+
case 38:
|
|
1100
|
+
error_2 = _j.sent();
|
|
988
1101
|
assistantContent = buildAssistantCodexErrorMessage(error_2);
|
|
989
|
-
return [3 /*break*/,
|
|
990
|
-
case
|
|
1102
|
+
return [3 /*break*/, 40];
|
|
1103
|
+
case 39:
|
|
991
1104
|
progressTracker.stop();
|
|
992
1105
|
return [7 /*endfinally*/];
|
|
993
|
-
case
|
|
1106
|
+
case 40:
|
|
994
1107
|
if (!assistantContent) {
|
|
995
1108
|
assistantContent = buildAssistantCodexErrorMessage(null);
|
|
996
1109
|
}
|
|
997
1110
|
finalNow = new Date();
|
|
998
|
-
|
|
1111
|
+
if (isSuperAdmin) {
|
|
1112
|
+
assistantDebug = buildAssistantDebugPayload({
|
|
1113
|
+
dataQuestion: dataQuestion,
|
|
1114
|
+
directive: lastDirective,
|
|
1115
|
+
directiveSource: directiveSource,
|
|
1116
|
+
toolResult: toolResult,
|
|
1117
|
+
toolResponseDebug: toolResponseDebug,
|
|
1118
|
+
toolError: toolError
|
|
1119
|
+
});
|
|
1120
|
+
}
|
|
1121
|
+
finalMetadata = __assign(__assign(__assign({ model: resolveCodexModel() }, (requestId ? { request_id: requestId } : {})), (toolResult ? { tool_result: toolResult } : {})), (assistantDebug ? { debug: assistantDebug } : {}));
|
|
999
1122
|
finalAssistantDoc = __assign(__assign({}, assistantDoc), { _id: assistantMessageId, content: assistantContent, metadata: finalMetadata, updatedAt: finalNow });
|
|
1000
|
-
if (!assistantMessageId) return [3 /*break*/,
|
|
1123
|
+
if (!assistantMessageId) return [3 /*break*/, 42];
|
|
1001
1124
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: assistantMessageId }, {
|
|
1002
1125
|
$set: {
|
|
1003
1126
|
content: assistantContent,
|
|
@@ -1005,43 +1128,47 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1005
1128
|
updatedAt: finalNow
|
|
1006
1129
|
}
|
|
1007
1130
|
})];
|
|
1008
|
-
case
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
case
|
|
1012
|
-
case
|
|
1013
|
-
|
|
1014
|
-
if (!(input.delete_files_after_run !== false)) return [3 /*break*/,
|
|
1131
|
+
case 41:
|
|
1132
|
+
_j.sent();
|
|
1133
|
+
_j.label = 42;
|
|
1134
|
+
case 42: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
|
|
1135
|
+
case 43:
|
|
1136
|
+
_j.sent();
|
|
1137
|
+
if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 45];
|
|
1015
1138
|
return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
|
|
1016
|
-
case
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
case
|
|
1139
|
+
case 44:
|
|
1140
|
+
_j.sent();
|
|
1141
|
+
_j.label = 45;
|
|
1142
|
+
case 45: return [2 /*return*/, __assign({ conversation: conversation, message: finalAssistantDoc }, (toolResult ? { tool_result: toolResult } : {}))];
|
|
1020
1143
|
}
|
|
1021
1144
|
});
|
|
1022
1145
|
});
|
|
1023
1146
|
}
|
|
1024
1147
|
function executeAiAssistantMongoRead(payload, context) {
|
|
1025
1148
|
return __awaiter(this, void 0, void 0, function () {
|
|
1026
|
-
var input, collection, _a, user, isSuperAdmin, customerId,
|
|
1149
|
+
var input, rawCollection, dbName, db, collectionResolution, collection, _a, user, isSuperAdmin, customerId, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalized, findOptions, documents, executedQuery, fallbackMeta, dateFallback, fallbackQuery, fallbackDocs, total, sanitizedDocuments, includeIds, display;
|
|
1027
1150
|
var _c, _d;
|
|
1028
1151
|
return __generator(this, function (_e) {
|
|
1029
1152
|
switch (_e.label) {
|
|
1030
1153
|
case 0:
|
|
1031
1154
|
input = payload || {};
|
|
1032
|
-
|
|
1033
|
-
if (!
|
|
1155
|
+
rawCollection = normalizeOptionalString(input.collection);
|
|
1156
|
+
if (!rawCollection) {
|
|
1034
1157
|
throw new Error('AI assistant mongo read: Collection is required.');
|
|
1035
1158
|
}
|
|
1036
|
-
|
|
1159
|
+
dbName = resolveAssistantDatabaseName(input.database, input.mongo);
|
|
1160
|
+
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
1161
|
+
return [4 /*yield*/, resolveAssistantCollectionName(db, dbName, rawCollection)];
|
|
1037
1162
|
case 1:
|
|
1163
|
+
collectionResolution = _e.sent();
|
|
1164
|
+
collection = collectionResolution.name || rawCollection;
|
|
1165
|
+
return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
|
|
1166
|
+
case 2:
|
|
1038
1167
|
_a = _e.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
|
|
1039
1168
|
if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
|
|
1040
1169
|
throw new Error('AI assistant mongo read: Access denied.');
|
|
1041
1170
|
}
|
|
1042
1171
|
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
1172
|
baseQuery = normalizeMongoQuery(input.query);
|
|
1046
1173
|
if (!isSuperAdmin && (collection === 'users' || collection === 'user-versions')) {
|
|
1047
1174
|
userId = normalizeOptionalString(user === null || user === void 0 ? void 0 : user._id);
|
|
@@ -1053,31 +1180,49 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
1053
1180
|
};
|
|
1054
1181
|
}
|
|
1055
1182
|
normalizedClient = normalizeOptionalString(input.id_client);
|
|
1056
|
-
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/,
|
|
1183
|
+
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 4];
|
|
1057
1184
|
return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
|
|
1058
|
-
case 2:
|
|
1059
|
-
_b = _e.sent();
|
|
1060
|
-
return [3 /*break*/, 4];
|
|
1061
1185
|
case 3:
|
|
1062
|
-
_b =
|
|
1063
|
-
|
|
1186
|
+
_b = _e.sent();
|
|
1187
|
+
return [3 /*break*/, 5];
|
|
1064
1188
|
case 4:
|
|
1189
|
+
_b = false;
|
|
1190
|
+
_e.label = 5;
|
|
1191
|
+
case 5:
|
|
1065
1192
|
shouldScopeByClient = _b;
|
|
1066
1193
|
clientScopedQuery = shouldScopeByClient
|
|
1067
1194
|
? applyClientScopeFilter(baseQuery, normalizedClient, isSuperAdmin)
|
|
1068
1195
|
: baseQuery;
|
|
1069
1196
|
scopedQuery = applyCustomerScopeFilter(clientScopedQuery, collection, customerId, isSuperAdmin);
|
|
1070
1197
|
normalized = normalizeAssistantFindOptions(input.options);
|
|
1071
|
-
|
|
1072
|
-
|
|
1198
|
+
findOptions = __assign(__assign({}, normalized.findOptions), { readPreference: AI_ASSISTANT_READ_PREFERENCE });
|
|
1199
|
+
return [4 /*yield*/, db.collection(collection).find(scopedQuery, findOptions).toArray()];
|
|
1200
|
+
case 6:
|
|
1073
1201
|
documents = _e.sent();
|
|
1202
|
+
executedQuery = scopedQuery;
|
|
1203
|
+
fallbackMeta = {};
|
|
1204
|
+
if (!!documents.length) return [3 /*break*/, 8];
|
|
1205
|
+
dateFallback = resolveQueryDateFieldFallback(scopedQuery);
|
|
1206
|
+
if (!dateFallback) return [3 /*break*/, 8];
|
|
1207
|
+
fallbackQuery = replaceQueryField(scopedQuery, dateFallback.from, dateFallback.to);
|
|
1208
|
+
fallbackMeta.dateField = __assign(__assign({}, dateFallback), { attempted: true, used: false });
|
|
1209
|
+
return [4 /*yield*/, db.collection(collection).find(fallbackQuery, findOptions).toArray()];
|
|
1210
|
+
case 7:
|
|
1211
|
+
fallbackDocs = _e.sent();
|
|
1212
|
+
if (fallbackDocs.length) {
|
|
1213
|
+
documents = fallbackDocs;
|
|
1214
|
+
executedQuery = fallbackQuery;
|
|
1215
|
+
fallbackMeta.dateField.used = true;
|
|
1216
|
+
}
|
|
1217
|
+
_e.label = 8;
|
|
1218
|
+
case 8:
|
|
1074
1219
|
total = null;
|
|
1075
|
-
if (!normalized.includeTotal) return [3 /*break*/,
|
|
1076
|
-
return [4 /*yield*/, db.collection(collection).countDocuments(
|
|
1077
|
-
case
|
|
1220
|
+
if (!normalized.includeTotal) return [3 /*break*/, 10];
|
|
1221
|
+
return [4 /*yield*/, db.collection(collection).countDocuments(executedQuery, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
|
|
1222
|
+
case 9:
|
|
1078
1223
|
total = _e.sent();
|
|
1079
|
-
_e.label =
|
|
1080
|
-
case
|
|
1224
|
+
_e.label = 10;
|
|
1225
|
+
case 10:
|
|
1081
1226
|
sanitizedDocuments = isSuperAdmin
|
|
1082
1227
|
? documents
|
|
1083
1228
|
: documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
|
|
@@ -1093,10 +1238,16 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
1093
1238
|
return [2 /*return*/, __assign({ documents: sanitizedDocuments, total: total, display: display }, (isSuperAdmin ? {
|
|
1094
1239
|
debug: {
|
|
1095
1240
|
collection: collection,
|
|
1241
|
+
collectionRequested: rawCollection,
|
|
1242
|
+
collectionResolved: collection,
|
|
1243
|
+
collectionMatched: collectionResolution.matched,
|
|
1244
|
+
collectionCandidates: collectionResolution.candidates,
|
|
1245
|
+
collectionScore: collectionResolution.score,
|
|
1096
1246
|
database: dbName,
|
|
1097
|
-
query:
|
|
1247
|
+
query: executedQuery,
|
|
1098
1248
|
options: normalized.findOptions,
|
|
1099
|
-
includeTotal: normalized.includeTotal
|
|
1249
|
+
includeTotal: normalized.includeTotal,
|
|
1250
|
+
fallbacks: fallbackMeta
|
|
1100
1251
|
}
|
|
1101
1252
|
} : {}))];
|
|
1102
1253
|
}
|
|
@@ -1105,25 +1256,29 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
1105
1256
|
}
|
|
1106
1257
|
function executeAiAssistantMongoAggregate(payload, context) {
|
|
1107
1258
|
return __awaiter(this, void 0, void 0, function () {
|
|
1108
|
-
var input, collection, _a, user, isSuperAdmin, customerId,
|
|
1259
|
+
var input, rawCollection, dbName, db, collectionResolution, collection, _a, user, isSuperAdmin, customerId, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, dateField, aggregateOptions, documents, executedPipeline, fallbackMeta, fallback, fallbackPipeline, fallbackDocs, createdFallback, createdPipeline, createdDocs, completionFallback, fallbackPipeline, fallbackDocs, unwindFallback, fallbackPipeline, fallbackDocs, sanitizedDocuments, includeIds, display;
|
|
1109
1260
|
var _c, _d;
|
|
1110
1261
|
return __generator(this, function (_e) {
|
|
1111
1262
|
switch (_e.label) {
|
|
1112
1263
|
case 0:
|
|
1113
1264
|
input = payload || {};
|
|
1114
|
-
|
|
1115
|
-
if (!
|
|
1265
|
+
rawCollection = normalizeOptionalString(input.collection);
|
|
1266
|
+
if (!rawCollection) {
|
|
1116
1267
|
throw new Error('AI assistant mongo aggregate: Collection is required.');
|
|
1117
1268
|
}
|
|
1118
|
-
|
|
1269
|
+
dbName = resolveAssistantDatabaseName(input.database, input.mongo);
|
|
1270
|
+
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
1271
|
+
return [4 /*yield*/, resolveAssistantCollectionName(db, dbName, rawCollection)];
|
|
1119
1272
|
case 1:
|
|
1273
|
+
collectionResolution = _e.sent();
|
|
1274
|
+
collection = collectionResolution.name || rawCollection;
|
|
1275
|
+
return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
|
|
1276
|
+
case 2:
|
|
1120
1277
|
_a = _e.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
|
|
1121
1278
|
if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
|
|
1122
1279
|
throw new Error('AI assistant mongo aggregate: Access denied.');
|
|
1123
1280
|
}
|
|
1124
1281
|
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
1282
|
baseQuery = normalizeMongoQuery(input.query);
|
|
1128
1283
|
if (!isSuperAdmin && (collection === 'users' || collection === 'user-versions')) {
|
|
1129
1284
|
userId = normalizeOptionalString(user === null || user === void 0 ? void 0 : user._id);
|
|
@@ -1135,15 +1290,15 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
1135
1290
|
};
|
|
1136
1291
|
}
|
|
1137
1292
|
normalizedClient = normalizeOptionalString(input.id_client);
|
|
1138
|
-
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/,
|
|
1293
|
+
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 4];
|
|
1139
1294
|
return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
|
|
1140
|
-
case 2:
|
|
1141
|
-
_b = _e.sent();
|
|
1142
|
-
return [3 /*break*/, 4];
|
|
1143
1295
|
case 3:
|
|
1144
|
-
_b =
|
|
1145
|
-
|
|
1296
|
+
_b = _e.sent();
|
|
1297
|
+
return [3 /*break*/, 5];
|
|
1146
1298
|
case 4:
|
|
1299
|
+
_b = false;
|
|
1300
|
+
_e.label = 5;
|
|
1301
|
+
case 5:
|
|
1147
1302
|
shouldScopeByClient = _b;
|
|
1148
1303
|
clientScopedQuery = shouldScopeByClient
|
|
1149
1304
|
? applyClientScopeFilter(baseQuery, normalizedClient, isSuperAdmin)
|
|
@@ -1157,66 +1312,91 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
1157
1312
|
if (containsForbiddenMongoOperators(limitedPipeline)) {
|
|
1158
1313
|
throw new Error('AI assistant mongo aggregate: Pipeline contains restricted operators.');
|
|
1159
1314
|
}
|
|
1315
|
+
aggregateOptions = __assign(__assign({}, normalizedOptions.aggregateOptions), { readPreference: AI_ASSISTANT_READ_PREFERENCE });
|
|
1160
1316
|
return [4 /*yield*/, db.collection(collection)
|
|
1161
|
-
.aggregate(limitedPipeline,
|
|
1317
|
+
.aggregate(limitedPipeline, aggregateOptions)
|
|
1162
1318
|
.toArray()];
|
|
1163
|
-
case
|
|
1319
|
+
case 6:
|
|
1164
1320
|
documents = _e.sent();
|
|
1165
1321
|
executedPipeline = limitedPipeline;
|
|
1166
1322
|
fallbackMeta = {};
|
|
1167
|
-
if (!(!documents.length && dateField)) return [3 /*break*/,
|
|
1323
|
+
if (!(!documents.length && dateField)) return [3 /*break*/, 10];
|
|
1168
1324
|
fallback = resolveAggregateDateFieldFallback(limitedPipeline);
|
|
1169
|
-
if (!fallback) return [3 /*break*/,
|
|
1325
|
+
if (!fallback) return [3 /*break*/, 8];
|
|
1170
1326
|
fallbackMeta.dateField = __assign(__assign({}, fallback), { attempted: true, used: false });
|
|
1171
1327
|
fallbackPipeline = replaceAggregateDateField(limitedPipeline, fallback.from, fallback.to);
|
|
1172
|
-
if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/,
|
|
1328
|
+
if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/, 8];
|
|
1173
1329
|
return [4 /*yield*/, db.collection(collection)
|
|
1174
|
-
.aggregate(fallbackPipeline,
|
|
1330
|
+
.aggregate(fallbackPipeline, aggregateOptions)
|
|
1175
1331
|
.toArray()];
|
|
1176
|
-
case
|
|
1332
|
+
case 7:
|
|
1177
1333
|
fallbackDocs = _e.sent();
|
|
1178
1334
|
if (fallbackDocs.length) {
|
|
1179
1335
|
documents = fallbackDocs;
|
|
1180
1336
|
executedPipeline = fallbackPipeline;
|
|
1181
1337
|
fallbackMeta.dateField.used = true;
|
|
1182
1338
|
}
|
|
1183
|
-
_e.label =
|
|
1184
|
-
case
|
|
1185
|
-
if (!(!documents.length && dateField !== 'createdAt')) return [3 /*break*/,
|
|
1339
|
+
_e.label = 8;
|
|
1340
|
+
case 8:
|
|
1341
|
+
if (!(!documents.length && dateField !== 'createdAt')) return [3 /*break*/, 10];
|
|
1186
1342
|
createdFallback = { from: dateField, to: 'createdAt', attempted: true, used: false };
|
|
1187
1343
|
createdPipeline = replaceAggregateDateField(limitedPipeline, dateField, 'createdAt');
|
|
1188
1344
|
fallbackMeta.dateFieldCreatedAt = createdFallback;
|
|
1189
|
-
if (!!containsForbiddenMongoOperators(createdPipeline)) return [3 /*break*/,
|
|
1345
|
+
if (!!containsForbiddenMongoOperators(createdPipeline)) return [3 /*break*/, 10];
|
|
1190
1346
|
return [4 /*yield*/, db.collection(collection)
|
|
1191
|
-
.aggregate(createdPipeline,
|
|
1347
|
+
.aggregate(createdPipeline, aggregateOptions)
|
|
1192
1348
|
.toArray()];
|
|
1193
|
-
case
|
|
1349
|
+
case 9:
|
|
1194
1350
|
createdDocs = _e.sent();
|
|
1195
1351
|
if (createdDocs.length) {
|
|
1196
1352
|
documents = createdDocs;
|
|
1197
1353
|
executedPipeline = createdPipeline;
|
|
1198
1354
|
fallbackMeta.dateFieldCreatedAt.used = true;
|
|
1199
1355
|
}
|
|
1200
|
-
_e.label =
|
|
1201
|
-
case
|
|
1202
|
-
if (
|
|
1356
|
+
_e.label = 10;
|
|
1357
|
+
case 10:
|
|
1358
|
+
if (!!documents.length) return [3 /*break*/, 12];
|
|
1359
|
+
completionFallback = resolveAggregateCompletionFallback(executedPipeline);
|
|
1360
|
+
if (!completionFallback) return [3 /*break*/, 12];
|
|
1361
|
+
fallbackMeta.completion = {
|
|
1362
|
+
field: completionFallback.field,
|
|
1363
|
+
sources: completionFallback.sources,
|
|
1364
|
+
attempted: true,
|
|
1365
|
+
used: false,
|
|
1366
|
+
statusFilter: !!completionFallback.statusFilter
|
|
1367
|
+
};
|
|
1368
|
+
fallbackPipeline = buildAggregateCompletionFallbackPipeline(executedPipeline, completionFallback);
|
|
1369
|
+
if (!(fallbackPipeline.length && !containsForbiddenMongoOperators(fallbackPipeline))) return [3 /*break*/, 12];
|
|
1370
|
+
return [4 /*yield*/, db.collection(collection)
|
|
1371
|
+
.aggregate(fallbackPipeline, aggregateOptions)
|
|
1372
|
+
.toArray()];
|
|
1373
|
+
case 11:
|
|
1374
|
+
fallbackDocs = _e.sent();
|
|
1375
|
+
if (fallbackDocs.length) {
|
|
1376
|
+
documents = fallbackDocs;
|
|
1377
|
+
executedPipeline = fallbackPipeline;
|
|
1378
|
+
fallbackMeta.completion.used = true;
|
|
1379
|
+
}
|
|
1380
|
+
_e.label = 12;
|
|
1381
|
+
case 12:
|
|
1382
|
+
if (!(documents.length <= 1)) return [3 /*break*/, 14];
|
|
1203
1383
|
unwindFallback = resolveAggregateUnwindFallback(executedPipeline);
|
|
1204
|
-
if (!unwindFallback) return [3 /*break*/,
|
|
1384
|
+
if (!unwindFallback) return [3 /*break*/, 14];
|
|
1205
1385
|
fallbackMeta.unwind = { path: unwindFallback.path, attempted: true, used: false };
|
|
1206
1386
|
fallbackPipeline = buildAggregateUnwindFallbackPipeline(executedPipeline, unwindFallback);
|
|
1207
|
-
if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/,
|
|
1387
|
+
if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/, 14];
|
|
1208
1388
|
return [4 /*yield*/, db.collection(collection)
|
|
1209
|
-
.aggregate(fallbackPipeline,
|
|
1389
|
+
.aggregate(fallbackPipeline, aggregateOptions)
|
|
1210
1390
|
.toArray()];
|
|
1211
|
-
case
|
|
1391
|
+
case 13:
|
|
1212
1392
|
fallbackDocs = _e.sent();
|
|
1213
1393
|
if (fallbackDocs.length > documents.length) {
|
|
1214
1394
|
documents = fallbackDocs;
|
|
1215
1395
|
executedPipeline = fallbackPipeline;
|
|
1216
1396
|
fallbackMeta.unwind.used = true;
|
|
1217
1397
|
}
|
|
1218
|
-
_e.label =
|
|
1219
|
-
case
|
|
1398
|
+
_e.label = 14;
|
|
1399
|
+
case 14:
|
|
1220
1400
|
sanitizedDocuments = isSuperAdmin
|
|
1221
1401
|
? documents
|
|
1222
1402
|
: documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
|
|
@@ -1229,6 +1409,11 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
1229
1409
|
return [2 /*return*/, __assign({ documents: sanitizedDocuments, display: display }, (isSuperAdmin ? {
|
|
1230
1410
|
debug: {
|
|
1231
1411
|
collection: collection,
|
|
1412
|
+
collectionRequested: rawCollection,
|
|
1413
|
+
collectionResolved: collection,
|
|
1414
|
+
collectionMatched: collectionResolution.matched,
|
|
1415
|
+
collectionCandidates: collectionResolution.candidates,
|
|
1416
|
+
collectionScore: collectionResolution.score,
|
|
1232
1417
|
database: dbName,
|
|
1233
1418
|
query: scopedQuery,
|
|
1234
1419
|
options: normalizedOptions.aggregateOptions,
|
|
@@ -1299,7 +1484,7 @@ function buildAssistantToolRequest(directive, payload) {
|
|
|
1299
1484
|
return request;
|
|
1300
1485
|
}
|
|
1301
1486
|
function buildAssistantToolResultPayload(directive, toolResponse) {
|
|
1302
|
-
var _a;
|
|
1487
|
+
var _a, _b, _c;
|
|
1303
1488
|
var directivePayload = directive.payload || {};
|
|
1304
1489
|
var documents = Array.isArray(toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.documents) ? toolResponse.documents : [];
|
|
1305
1490
|
var includeIds = ((_a = directivePayload === null || directivePayload === void 0 ? void 0 : directivePayload.options) === null || _a === void 0 ? void 0 : _a.includeIds) === true;
|
|
@@ -1316,17 +1501,22 @@ function buildAssistantToolResultPayload(directive, toolResponse) {
|
|
|
1316
1501
|
});
|
|
1317
1502
|
var total = typeof (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.total) === 'number' ? toolResponse.total : null;
|
|
1318
1503
|
var rowCount = documents.length || trimmedDisplay.rowCount;
|
|
1319
|
-
var
|
|
1504
|
+
var requestedCollection = normalizeOptionalString(directivePayload === null || directivePayload === void 0 ? void 0 : directivePayload.collection);
|
|
1505
|
+
var resolvedCollection = normalizeOptionalString((_b = toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) === null || _b === void 0 ? void 0 : _b.collectionResolved)
|
|
1506
|
+
|| normalizeOptionalString((_c = toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) === null || _c === void 0 ? void 0 : _c.collection)
|
|
1507
|
+
|| requestedCollection
|
|
1508
|
+
|| '';
|
|
1320
1509
|
var result = {
|
|
1321
1510
|
type: directive.type === 'aggregate' ? 'mongo_agg' : 'mongo_read',
|
|
1322
1511
|
input: directivePayload,
|
|
1323
1512
|
output: {
|
|
1324
1513
|
display: trimmedDisplay,
|
|
1325
1514
|
total: total !== null ? total : undefined,
|
|
1326
|
-
collection:
|
|
1515
|
+
collection: resolvedCollection || undefined,
|
|
1327
1516
|
rowCount: rowCount,
|
|
1328
1517
|
columns: trimmedDisplay.columns,
|
|
1329
|
-
truncated: trimmedDisplay.truncated
|
|
1518
|
+
truncated: trimmedDisplay.truncated,
|
|
1519
|
+
debug: (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object' ? toolResponse.debug : undefined
|
|
1330
1520
|
}
|
|
1331
1521
|
};
|
|
1332
1522
|
return {
|
|
@@ -1382,6 +1572,82 @@ function buildAssistantToolFallbackResponse(result) {
|
|
|
1382
1572
|
}
|
|
1383
1573
|
return lines.join('\n').trim();
|
|
1384
1574
|
}
|
|
1575
|
+
function buildAssistantDebugPayload(params) {
|
|
1576
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
|
|
1577
|
+
var notes = [];
|
|
1578
|
+
if (params.dataQuestion) {
|
|
1579
|
+
notes.push('Detected a data request; tool call required.');
|
|
1580
|
+
}
|
|
1581
|
+
if (params.directiveSource === 'forced') {
|
|
1582
|
+
notes.push('Assistant response omitted a MONGO_* directive; ran a directive-only pass.');
|
|
1583
|
+
}
|
|
1584
|
+
var directive = params.directive;
|
|
1585
|
+
var directivePayload = (directive === null || directive === void 0 ? void 0 : directive.payload) || {};
|
|
1586
|
+
var rawCollection = normalizeOptionalString(directivePayload === null || directivePayload === void 0 ? void 0 : directivePayload.collection);
|
|
1587
|
+
var debugCollectionRequested = normalizeOptionalString((_a = params.toolResponseDebug) === null || _a === void 0 ? void 0 : _a.collectionRequested);
|
|
1588
|
+
var debugCollectionResolved = normalizeOptionalString((_b = params.toolResponseDebug) === null || _b === void 0 ? void 0 : _b.collectionResolved);
|
|
1589
|
+
var debugCollection = normalizeOptionalString((_c = params.toolResponseDebug) === null || _c === void 0 ? void 0 : _c.collection);
|
|
1590
|
+
var requestedCollection = debugCollectionRequested || rawCollection;
|
|
1591
|
+
var resolvedCollection = debugCollectionResolved || debugCollection || requestedCollection;
|
|
1592
|
+
var matchedCollection = typeof ((_d = params.toolResponseDebug) === null || _d === void 0 ? void 0 : _d.collectionMatched) === 'boolean'
|
|
1593
|
+
? params.toolResponseDebug.collectionMatched
|
|
1594
|
+
: undefined;
|
|
1595
|
+
var candidateCollections = Array.isArray((_e = params.toolResponseDebug) === null || _e === void 0 ? void 0 : _e.collectionCandidates)
|
|
1596
|
+
? params.toolResponseDebug.collectionCandidates.filter(Boolean)
|
|
1597
|
+
: [];
|
|
1598
|
+
if (requestedCollection && resolvedCollection && requestedCollection !== resolvedCollection) {
|
|
1599
|
+
notes.push("Resolved collection \"".concat(requestedCollection, "\" -> \"").concat(resolvedCollection, "\"."));
|
|
1600
|
+
}
|
|
1601
|
+
else if (matchedCollection === false && candidateCollections.length) {
|
|
1602
|
+
notes.push("No direct collection match; candidates: ".concat(candidateCollections.join(', '), "."));
|
|
1603
|
+
}
|
|
1604
|
+
if (((_f = params.toolResult) === null || _f === void 0 ? void 0 : _f.type) === 'mongo_agg') {
|
|
1605
|
+
notes.push('Used aggregation for grouped/breakdown request.');
|
|
1606
|
+
}
|
|
1607
|
+
else if (((_g = params.toolResult) === null || _g === void 0 ? void 0 : _g.type) === 'mongo_read') {
|
|
1608
|
+
notes.push('Used read query for list/count request.');
|
|
1609
|
+
}
|
|
1610
|
+
var fallbackInfo = (_h = params.toolResponseDebug) === null || _h === void 0 ? void 0 : _h.fallbacks;
|
|
1611
|
+
if ((_j = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateField) === null || _j === void 0 ? void 0 : _j.used) {
|
|
1612
|
+
notes.push("Retried with date field fallback ".concat(fallbackInfo.dateField.from, " -> ").concat(fallbackInfo.dateField.to, "."));
|
|
1613
|
+
}
|
|
1614
|
+
if ((_k = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateFieldCreatedAt) === null || _k === void 0 ? void 0 : _k.used) {
|
|
1615
|
+
notes.push("Retried with date field fallback ".concat(fallbackInfo.dateFieldCreatedAt.from, " -> ").concat(fallbackInfo.dateFieldCreatedAt.to, "."));
|
|
1616
|
+
}
|
|
1617
|
+
if ((_l = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.unwind) === null || _l === void 0 ? void 0 : _l.used) {
|
|
1618
|
+
notes.push("Applied unwind fallback on ".concat(fallbackInfo.unwind.path, "."));
|
|
1619
|
+
}
|
|
1620
|
+
if (params.toolError) {
|
|
1621
|
+
var errorMessage = ((_m = params.toolError) === null || _m === void 0 ? void 0 : _m.message) || String(params.toolError || '');
|
|
1622
|
+
if (errorMessage) {
|
|
1623
|
+
notes.push("Tool error: ".concat(errorMessage));
|
|
1624
|
+
}
|
|
1625
|
+
}
|
|
1626
|
+
return {
|
|
1627
|
+
decision: {
|
|
1628
|
+
dataQuestion: params.dataQuestion,
|
|
1629
|
+
directiveSource: params.directiveSource
|
|
1630
|
+
},
|
|
1631
|
+
directive: directive ? {
|
|
1632
|
+
type: directive.type,
|
|
1633
|
+
payload: directivePayload,
|
|
1634
|
+
rawLine: directive.rawLine
|
|
1635
|
+
} : null,
|
|
1636
|
+
collection: resolvedCollection || requestedCollection || undefined,
|
|
1637
|
+
collectionRequested: requestedCollection || undefined,
|
|
1638
|
+
collectionResolved: resolvedCollection || undefined,
|
|
1639
|
+
collectionMatched: matchedCollection,
|
|
1640
|
+
collectionCandidates: candidateCollections.length ? candidateCollections : undefined,
|
|
1641
|
+
collectionScore: typeof ((_o = params.toolResponseDebug) === null || _o === void 0 ? void 0 : _o.collectionScore) === 'number'
|
|
1642
|
+
? params.toolResponseDebug.collectionScore
|
|
1643
|
+
: undefined,
|
|
1644
|
+
query: ((_p = params.toolResponseDebug) === null || _p === void 0 ? void 0 : _p.query) || undefined,
|
|
1645
|
+
pipeline: ((_q = params.toolResponseDebug) === null || _q === void 0 ? void 0 : _q.executedPipeline) || ((_r = params.toolResponseDebug) === null || _r === void 0 ? void 0 : _r.originalPipeline) || undefined,
|
|
1646
|
+
options: ((_s = params.toolResponseDebug) === null || _s === void 0 ? void 0 : _s.options) || undefined,
|
|
1647
|
+
fallbacks: ((_t = params.toolResponseDebug) === null || _t === void 0 ? void 0 : _t.fallbacks) || undefined,
|
|
1648
|
+
notes: notes
|
|
1649
|
+
};
|
|
1650
|
+
}
|
|
1385
1651
|
function buildAssistantToolErrorMessage(error, directive, request) {
|
|
1386
1652
|
var _a, _b;
|
|
1387
1653
|
var rawMessage = normalizeOptionalString(error === null || error === void 0 ? void 0 : error.message) || 'Unable to access data.';
|
|
@@ -2006,7 +2272,18 @@ function normalizeAssistantAggregatePipeline(pipeline) {
|
|
|
2006
2272
|
if (!Array.isArray(pipeline)) {
|
|
2007
2273
|
return [];
|
|
2008
2274
|
}
|
|
2009
|
-
return pipeline
|
|
2275
|
+
return pipeline
|
|
2276
|
+
.filter(function (stage) { return stage && typeof stage === 'object' && !Array.isArray(stage); })
|
|
2277
|
+
.map(function (stage) {
|
|
2278
|
+
var next = __assign({}, stage);
|
|
2279
|
+
if (next.$match && typeof next.$match === 'object') {
|
|
2280
|
+
next.$match = applyAssistantNameRegexToQuery(next.$match);
|
|
2281
|
+
}
|
|
2282
|
+
if (next.$geoNear && typeof next.$geoNear === 'object' && next.$geoNear.query) {
|
|
2283
|
+
next.$geoNear = __assign(__assign({}, next.$geoNear), { query: applyAssistantNameRegexToQuery(next.$geoNear.query) });
|
|
2284
|
+
}
|
|
2285
|
+
return next;
|
|
2286
|
+
});
|
|
2010
2287
|
}
|
|
2011
2288
|
function buildAssistantAggregatePipeline(query, pipeline) {
|
|
2012
2289
|
var _a;
|
|
@@ -2089,6 +2366,172 @@ function resolveAggregateDateFieldFallback(pipeline) {
|
|
|
2089
2366
|
}
|
|
2090
2367
|
return { from: dateField, to: fallback };
|
|
2091
2368
|
}
|
|
2369
|
+
function normalizeAggregateFieldList(values) {
|
|
2370
|
+
var seen = new Set();
|
|
2371
|
+
var result = [];
|
|
2372
|
+
values.forEach(function (value) {
|
|
2373
|
+
var normalized = normalizeOptionalString(value);
|
|
2374
|
+
if (!normalized) {
|
|
2375
|
+
return;
|
|
2376
|
+
}
|
|
2377
|
+
if (seen.has(normalized)) {
|
|
2378
|
+
return;
|
|
2379
|
+
}
|
|
2380
|
+
seen.add(normalized);
|
|
2381
|
+
result.push(normalized);
|
|
2382
|
+
});
|
|
2383
|
+
return result;
|
|
2384
|
+
}
|
|
2385
|
+
function isCompletionFieldName(value) {
|
|
2386
|
+
return String(value || '').toLowerCase().includes('complete');
|
|
2387
|
+
}
|
|
2388
|
+
function isDateLikeFieldName(value) {
|
|
2389
|
+
var normalized = String(value || '').toLowerCase();
|
|
2390
|
+
return normalized.includes('date') || normalized.endsWith('_at') || normalized.endsWith('at');
|
|
2391
|
+
}
|
|
2392
|
+
function matchContainsField(value, field) {
|
|
2393
|
+
if (!value || typeof value !== 'object') {
|
|
2394
|
+
return false;
|
|
2395
|
+
}
|
|
2396
|
+
if (Array.isArray(value)) {
|
|
2397
|
+
return value.some(function (entry) { return matchContainsField(entry, field); });
|
|
2398
|
+
}
|
|
2399
|
+
return Object.keys(value).some(function (key) {
|
|
2400
|
+
if (key === field) {
|
|
2401
|
+
return true;
|
|
2402
|
+
}
|
|
2403
|
+
if (key.startsWith('$')) {
|
|
2404
|
+
return matchContainsField(value[key], field);
|
|
2405
|
+
}
|
|
2406
|
+
if (value[key] && typeof value[key] === 'object') {
|
|
2407
|
+
return matchContainsField(value[key], field);
|
|
2408
|
+
}
|
|
2409
|
+
return false;
|
|
2410
|
+
});
|
|
2411
|
+
}
|
|
2412
|
+
function resolveAggregateCompletionFallback(pipeline) {
|
|
2413
|
+
var e_1, _a;
|
|
2414
|
+
if (!Array.isArray(pipeline)) {
|
|
2415
|
+
return null;
|
|
2416
|
+
}
|
|
2417
|
+
var candidateField = '';
|
|
2418
|
+
var candidateSources = [];
|
|
2419
|
+
for (var i = 0; i < pipeline.length; i += 1) {
|
|
2420
|
+
var stage = pipeline[i];
|
|
2421
|
+
if (!stage || typeof stage !== 'object' || !stage.$addFields || typeof stage.$addFields !== 'object') {
|
|
2422
|
+
continue;
|
|
2423
|
+
}
|
|
2424
|
+
var addFields = stage.$addFields;
|
|
2425
|
+
try {
|
|
2426
|
+
for (var _b = (e_1 = void 0, __values(Object.keys(addFields))), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
2427
|
+
var key = _c.value;
|
|
2428
|
+
if (!isCompletionFieldName(key)) {
|
|
2429
|
+
continue;
|
|
2430
|
+
}
|
|
2431
|
+
var sources = extractExpressionFieldPaths(addFields[key])
|
|
2432
|
+
.filter(function (field) { return isDateLikeFieldName(field); });
|
|
2433
|
+
if (sources.length) {
|
|
2434
|
+
candidateField = key;
|
|
2435
|
+
candidateSources = sources;
|
|
2436
|
+
break;
|
|
2437
|
+
}
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
2441
|
+
finally {
|
|
2442
|
+
try {
|
|
2443
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
2444
|
+
}
|
|
2445
|
+
finally { if (e_1) throw e_1.error; }
|
|
2446
|
+
}
|
|
2447
|
+
if (candidateField) {
|
|
2448
|
+
break;
|
|
2449
|
+
}
|
|
2450
|
+
}
|
|
2451
|
+
if (!candidateField || !candidateSources.length) {
|
|
2452
|
+
return null;
|
|
2453
|
+
}
|
|
2454
|
+
var matchIndex = -1;
|
|
2455
|
+
var matchCondition = null;
|
|
2456
|
+
var matchStage = null;
|
|
2457
|
+
for (var i = 0; i < pipeline.length; i += 1) {
|
|
2458
|
+
var stage = pipeline[i];
|
|
2459
|
+
if (!stage || typeof stage !== 'object' || !stage.$match || typeof stage.$match !== 'object') {
|
|
2460
|
+
continue;
|
|
2461
|
+
}
|
|
2462
|
+
if (Object.prototype.hasOwnProperty.call(stage.$match, candidateField)) {
|
|
2463
|
+
matchIndex = i;
|
|
2464
|
+
matchCondition = stage.$match[candidateField];
|
|
2465
|
+
matchStage = stage.$match;
|
|
2466
|
+
break;
|
|
2467
|
+
}
|
|
2468
|
+
}
|
|
2469
|
+
if (matchIndex === -1 || !matchStage) {
|
|
2470
|
+
return null;
|
|
2471
|
+
}
|
|
2472
|
+
var normalizedSources = normalizeAggregateFieldList(__spreadArray(__spreadArray([], __read(candidateSources), false), [
|
|
2473
|
+
'createdAt',
|
|
2474
|
+
'date_created'
|
|
2475
|
+
], false));
|
|
2476
|
+
if (!normalizedSources.length) {
|
|
2477
|
+
return null;
|
|
2478
|
+
}
|
|
2479
|
+
var hasStatus = matchContainsField(matchStage, 'status') || matchContainsField(matchStage, 'state');
|
|
2480
|
+
var statusFilter = !hasStatus && isCompletionFieldName(candidateField)
|
|
2481
|
+
? { $or: [{ status: { $regex: 'complete', $options: 'i' } }, { state: { $regex: 'complete', $options: 'i' } }] }
|
|
2482
|
+
: null;
|
|
2483
|
+
return {
|
|
2484
|
+
matchIndex: matchIndex,
|
|
2485
|
+
field: candidateField,
|
|
2486
|
+
sources: normalizedSources,
|
|
2487
|
+
matchCondition: matchCondition,
|
|
2488
|
+
statusFilter: statusFilter
|
|
2489
|
+
};
|
|
2490
|
+
}
|
|
2491
|
+
function buildAggregateCompletionFallbackPipeline(pipeline, fallback) {
|
|
2492
|
+
var _a;
|
|
2493
|
+
var buildIfNullChain = function (fields) {
|
|
2494
|
+
if (!fields.length) {
|
|
2495
|
+
return null;
|
|
2496
|
+
}
|
|
2497
|
+
var expr = "$".concat(fields[fields.length - 1]);
|
|
2498
|
+
for (var i = fields.length - 2; i >= 0; i -= 1) {
|
|
2499
|
+
expr = { $ifNull: ["$".concat(fields[i]), expr] };
|
|
2500
|
+
}
|
|
2501
|
+
return expr;
|
|
2502
|
+
};
|
|
2503
|
+
var matchStage = (_a = pipeline[fallback.matchIndex]) === null || _a === void 0 ? void 0 : _a.$match;
|
|
2504
|
+
if (!matchStage || typeof matchStage !== 'object') {
|
|
2505
|
+
return pipeline;
|
|
2506
|
+
}
|
|
2507
|
+
var orConditions = fallback.sources.map(function (field) {
|
|
2508
|
+
var _a;
|
|
2509
|
+
return (_a = {}, _a[field] = fallback.matchCondition, _a);
|
|
2510
|
+
});
|
|
2511
|
+
var nextMatch = __assign({}, matchStage);
|
|
2512
|
+
delete nextMatch[fallback.field];
|
|
2513
|
+
var andParts = [];
|
|
2514
|
+
if (Object.keys(nextMatch).length) {
|
|
2515
|
+
andParts.push(nextMatch);
|
|
2516
|
+
}
|
|
2517
|
+
andParts.push({ $or: orConditions });
|
|
2518
|
+
if (fallback.statusFilter) {
|
|
2519
|
+
andParts.push(fallback.statusFilter);
|
|
2520
|
+
}
|
|
2521
|
+
var mergedMatch = andParts.length === 1 ? andParts[0] : { $and: andParts };
|
|
2522
|
+
return pipeline.map(function (stage, index) {
|
|
2523
|
+
var _a;
|
|
2524
|
+
if (index === fallback.matchIndex) {
|
|
2525
|
+
return { $match: mergedMatch };
|
|
2526
|
+
}
|
|
2527
|
+
if (stage && typeof stage === 'object' && stage.$addFields && typeof stage.$addFields === 'object') {
|
|
2528
|
+
if (Object.prototype.hasOwnProperty.call(stage.$addFields, fallback.field)) {
|
|
2529
|
+
return __assign(__assign({}, stage), { $addFields: __assign(__assign({}, stage.$addFields), (_a = {}, _a[fallback.field] = buildIfNullChain(fallback.sources), _a)) });
|
|
2530
|
+
}
|
|
2531
|
+
}
|
|
2532
|
+
return stage;
|
|
2533
|
+
});
|
|
2534
|
+
}
|
|
2092
2535
|
function resolveAggregateUnwindFallback(pipeline) {
|
|
2093
2536
|
var groupIndex = findAggregateGroupIndex(pipeline);
|
|
2094
2537
|
if (groupIndex === -1) {
|
|
@@ -2275,10 +2718,302 @@ function normalizeMongoQuery(query) {
|
|
|
2275
2718
|
if (containsForbiddenMongoOperators(normalized)) {
|
|
2276
2719
|
throw new Error('AI assistant mongo read: Query contains restricted operators.');
|
|
2277
2720
|
}
|
|
2278
|
-
return normalized;
|
|
2721
|
+
return applyAssistantNameRegexToQuery(normalized);
|
|
2722
|
+
}
|
|
2723
|
+
function shouldApplyAssistantNameRegex(field) {
|
|
2724
|
+
var normalized = String(field || '').toLowerCase().trim();
|
|
2725
|
+
if (!normalized) {
|
|
2726
|
+
return false;
|
|
2727
|
+
}
|
|
2728
|
+
if (normalized.startsWith('$')) {
|
|
2729
|
+
return false;
|
|
2730
|
+
}
|
|
2731
|
+
if (isAssistantIdField(normalized)) {
|
|
2732
|
+
return false;
|
|
2733
|
+
}
|
|
2734
|
+
if (normalized === 'id' || normalized.endsWith('_id')) {
|
|
2735
|
+
return false;
|
|
2736
|
+
}
|
|
2737
|
+
var tokens = normalized.split(/[^a-z0-9]+/g).filter(Boolean);
|
|
2738
|
+
var targetTokens = new Set(['customer', 'well', 'chemical']);
|
|
2739
|
+
var hasTargetToken = tokens.some(function (token) { return targetTokens.has(token); });
|
|
2740
|
+
if (hasTargetToken) {
|
|
2741
|
+
return true;
|
|
2742
|
+
}
|
|
2743
|
+
if (tokens.includes('name')) {
|
|
2744
|
+
return true;
|
|
2745
|
+
}
|
|
2746
|
+
return /(^|[._-])name$/i.test(normalized);
|
|
2747
|
+
}
|
|
2748
|
+
function escapeRegexValue(value) {
|
|
2749
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
2750
|
+
}
|
|
2751
|
+
function applyAssistantNameRegexToQuery(query) {
|
|
2752
|
+
if (Array.isArray(query)) {
|
|
2753
|
+
return query.map(function (entry) { return applyAssistantNameRegexToQuery(entry); });
|
|
2754
|
+
}
|
|
2755
|
+
if (!query || typeof query !== 'object' || query instanceof Date || query instanceof RegExp || isMongoObjectId(query)) {
|
|
2756
|
+
return query;
|
|
2757
|
+
}
|
|
2758
|
+
var result = {};
|
|
2759
|
+
Object.keys(query).forEach(function (key) {
|
|
2760
|
+
var value = query[key];
|
|
2761
|
+
if (key.startsWith('$')) {
|
|
2762
|
+
result[key] = applyAssistantNameRegexToQuery(value);
|
|
2763
|
+
return;
|
|
2764
|
+
}
|
|
2765
|
+
if (typeof value === 'string' && shouldApplyAssistantNameRegex(key)) {
|
|
2766
|
+
var trimmed = value.trim();
|
|
2767
|
+
result[key] = trimmed ? new RegExp(escapeRegexValue(trimmed), 'i') : value;
|
|
2768
|
+
return;
|
|
2769
|
+
}
|
|
2770
|
+
if (value && typeof value === 'object') {
|
|
2771
|
+
result[key] = applyAssistantNameRegexToQuery(value);
|
|
2772
|
+
return;
|
|
2773
|
+
}
|
|
2774
|
+
result[key] = value;
|
|
2775
|
+
});
|
|
2776
|
+
return result;
|
|
2777
|
+
}
|
|
2778
|
+
function normalizeCollectionKey(value) {
|
|
2779
|
+
return String(value || '').toLowerCase().replace(/[^a-z0-9]/g, '');
|
|
2780
|
+
}
|
|
2781
|
+
function normalizeCollectionToken(token) {
|
|
2782
|
+
var trimmed = token.trim();
|
|
2783
|
+
if (!trimmed) {
|
|
2784
|
+
return [];
|
|
2785
|
+
}
|
|
2786
|
+
var tokens = new Set([trimmed]);
|
|
2787
|
+
if (trimmed.length > 4
|
|
2788
|
+
&& trimmed.endsWith('s')
|
|
2789
|
+
&& !trimmed.endsWith('ss')
|
|
2790
|
+
&& !trimmed.endsWith('us')
|
|
2791
|
+
&& !trimmed.endsWith('is')) {
|
|
2792
|
+
tokens.add(trimmed.slice(0, -1));
|
|
2793
|
+
}
|
|
2794
|
+
return Array.from(tokens);
|
|
2795
|
+
}
|
|
2796
|
+
function tokenizeCollectionText(value) {
|
|
2797
|
+
var rawTokens = String(value || '')
|
|
2798
|
+
.toLowerCase()
|
|
2799
|
+
.split(/[^a-z0-9]+/g)
|
|
2800
|
+
.map(function (token) { return token.trim(); })
|
|
2801
|
+
.filter(Boolean);
|
|
2802
|
+
var tokens = [];
|
|
2803
|
+
rawTokens.forEach(function (token) {
|
|
2804
|
+
normalizeCollectionToken(token).forEach(function (normalized) {
|
|
2805
|
+
if (!AI_ASSISTANT_COLLECTION_STOPWORDS.has(normalized)) {
|
|
2806
|
+
tokens.push(normalized);
|
|
2807
|
+
}
|
|
2808
|
+
});
|
|
2809
|
+
});
|
|
2810
|
+
return Array.from(new Set(tokens));
|
|
2811
|
+
}
|
|
2812
|
+
function listAssistantCollections(db, dbName) {
|
|
2813
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2814
|
+
var cacheKey, cached, now, collections, names, _a;
|
|
2815
|
+
return __generator(this, function (_b) {
|
|
2816
|
+
switch (_b.label) {
|
|
2817
|
+
case 0:
|
|
2818
|
+
cacheKey = normalizeOptionalString(dbName) || 'default';
|
|
2819
|
+
cached = AI_ASSISTANT_COLLECTION_CACHE.get(cacheKey);
|
|
2820
|
+
now = Date.now();
|
|
2821
|
+
if (cached && now - cached.updatedAt < AI_ASSISTANT_COLLECTION_CACHE_TTL_MS) {
|
|
2822
|
+
return [2 /*return*/, cached.names];
|
|
2823
|
+
}
|
|
2824
|
+
_b.label = 1;
|
|
2825
|
+
case 1:
|
|
2826
|
+
_b.trys.push([1, 3, , 4]);
|
|
2827
|
+
return [4 /*yield*/, db.listCollections({}, { nameOnly: true }).toArray()];
|
|
2828
|
+
case 2:
|
|
2829
|
+
collections = _b.sent();
|
|
2830
|
+
names = Array.isArray(collections)
|
|
2831
|
+
? collections.map(function (entry) { return normalizeOptionalString(entry === null || entry === void 0 ? void 0 : entry.name); }).filter(Boolean)
|
|
2832
|
+
: [];
|
|
2833
|
+
AI_ASSISTANT_COLLECTION_CACHE.set(cacheKey, { names: names, updatedAt: now });
|
|
2834
|
+
return [2 /*return*/, names];
|
|
2835
|
+
case 3:
|
|
2836
|
+
_a = _b.sent();
|
|
2837
|
+
return [2 /*return*/, (cached === null || cached === void 0 ? void 0 : cached.names) || []];
|
|
2838
|
+
case 4: return [2 /*return*/];
|
|
2839
|
+
}
|
|
2840
|
+
});
|
|
2841
|
+
});
|
|
2842
|
+
}
|
|
2843
|
+
function scoreCollectionMatch(requestedTokens, candidateName) {
|
|
2844
|
+
if (!requestedTokens.length) {
|
|
2845
|
+
return 0;
|
|
2846
|
+
}
|
|
2847
|
+
var candidateTokens = tokenizeCollectionText(candidateName);
|
|
2848
|
+
if (!candidateTokens.length) {
|
|
2849
|
+
return 0;
|
|
2850
|
+
}
|
|
2851
|
+
var score = 0;
|
|
2852
|
+
requestedTokens.forEach(function (token) {
|
|
2853
|
+
if (candidateTokens.includes(token)) {
|
|
2854
|
+
score += 10;
|
|
2855
|
+
}
|
|
2856
|
+
});
|
|
2857
|
+
var requestedKey = normalizeCollectionKey(requestedTokens.join('-'));
|
|
2858
|
+
var candidateKey = normalizeCollectionKey(candidateName);
|
|
2859
|
+
if (candidateKey === requestedKey && requestedKey) {
|
|
2860
|
+
score += 50;
|
|
2861
|
+
}
|
|
2862
|
+
else if (requestedKey && (candidateKey.includes(requestedKey) || requestedKey.includes(candidateKey))) {
|
|
2863
|
+
score += 20;
|
|
2864
|
+
}
|
|
2865
|
+
return score;
|
|
2866
|
+
}
|
|
2867
|
+
function findBestCollectionMatch(requested, collectionNames) {
|
|
2868
|
+
var requestedTokens = tokenizeCollectionText(requested);
|
|
2869
|
+
if (!requestedTokens.length || !collectionNames.length) {
|
|
2870
|
+
return null;
|
|
2871
|
+
}
|
|
2872
|
+
var best = null;
|
|
2873
|
+
collectionNames.forEach(function (name) {
|
|
2874
|
+
var score = scoreCollectionMatch(requestedTokens, name);
|
|
2875
|
+
if (!best || score > best.score) {
|
|
2876
|
+
best = { name: name, score: score };
|
|
2877
|
+
}
|
|
2878
|
+
});
|
|
2879
|
+
return best;
|
|
2880
|
+
}
|
|
2881
|
+
function resolveAssistantCollectionName(db, dbName, requested) {
|
|
2882
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2883
|
+
var trimmed, collectionNames, best, candidates;
|
|
2884
|
+
return __generator(this, function (_a) {
|
|
2885
|
+
switch (_a.label) {
|
|
2886
|
+
case 0:
|
|
2887
|
+
trimmed = normalizeOptionalString(requested);
|
|
2888
|
+
if (!trimmed) {
|
|
2889
|
+
return [2 /*return*/, { name: '', matched: false, candidates: [], score: 0 }];
|
|
2890
|
+
}
|
|
2891
|
+
return [4 /*yield*/, listAssistantCollections(db, dbName)];
|
|
2892
|
+
case 1:
|
|
2893
|
+
collectionNames = _a.sent();
|
|
2894
|
+
if (collectionNames.includes(trimmed)) {
|
|
2895
|
+
return [2 /*return*/, { name: trimmed, matched: true, candidates: [], score: 100 }];
|
|
2896
|
+
}
|
|
2897
|
+
best = findBestCollectionMatch(trimmed, collectionNames);
|
|
2898
|
+
if (best && best.score >= 20) {
|
|
2899
|
+
return [2 /*return*/, { name: best.name, matched: true, candidates: [], score: best.score }];
|
|
2900
|
+
}
|
|
2901
|
+
candidates = collectionNames
|
|
2902
|
+
.map(function (name) { return ({ name: name, score: scoreCollectionMatch(tokenizeCollectionText(trimmed), name) }); })
|
|
2903
|
+
.filter(function (entry) { return entry.score > 0; })
|
|
2904
|
+
.sort(function (a, b) { return b.score - a.score; })
|
|
2905
|
+
.slice(0, 5)
|
|
2906
|
+
.map(function (entry) { return entry.name; });
|
|
2907
|
+
return [2 /*return*/, { name: trimmed, matched: false, candidates: candidates, score: (best === null || best === void 0 ? void 0 : best.score) || 0 }];
|
|
2908
|
+
}
|
|
2909
|
+
});
|
|
2910
|
+
});
|
|
2911
|
+
}
|
|
2912
|
+
function resolveAssistantCollectionHints(message, dbName, db) {
|
|
2913
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2914
|
+
var text, collectionNames, tokens;
|
|
2915
|
+
return __generator(this, function (_a) {
|
|
2916
|
+
switch (_a.label) {
|
|
2917
|
+
case 0:
|
|
2918
|
+
text = normalizeOptionalString(message);
|
|
2919
|
+
if (!text) {
|
|
2920
|
+
return [2 /*return*/, []];
|
|
2921
|
+
}
|
|
2922
|
+
return [4 /*yield*/, listAssistantCollections(db, dbName)];
|
|
2923
|
+
case 1:
|
|
2924
|
+
collectionNames = _a.sent();
|
|
2925
|
+
if (!collectionNames.length) {
|
|
2926
|
+
return [2 /*return*/, []];
|
|
2927
|
+
}
|
|
2928
|
+
tokens = tokenizeCollectionText(text);
|
|
2929
|
+
if (!tokens.length) {
|
|
2930
|
+
return [2 /*return*/, []];
|
|
2931
|
+
}
|
|
2932
|
+
return [2 /*return*/, collectionNames
|
|
2933
|
+
.map(function (name) { return ({ name: name, score: scoreCollectionMatch(tokens, name) }); })
|
|
2934
|
+
.filter(function (entry) { return entry.score > 0; })
|
|
2935
|
+
.sort(function (a, b) { return b.score - a.score; })
|
|
2936
|
+
.slice(0, 5)
|
|
2937
|
+
.map(function (entry) { return entry.name; })];
|
|
2938
|
+
}
|
|
2939
|
+
});
|
|
2940
|
+
});
|
|
2941
|
+
}
|
|
2942
|
+
function findQueryDateField(query) {
|
|
2943
|
+
var e_2, _a, e_3, _b;
|
|
2944
|
+
if (!query || typeof query !== 'object') {
|
|
2945
|
+
return null;
|
|
2946
|
+
}
|
|
2947
|
+
if (Array.isArray(query)) {
|
|
2948
|
+
try {
|
|
2949
|
+
for (var query_1 = __values(query), query_1_1 = query_1.next(); !query_1_1.done; query_1_1 = query_1.next()) {
|
|
2950
|
+
var entry = query_1_1.value;
|
|
2951
|
+
var found = findQueryDateField(entry);
|
|
2952
|
+
if (found) {
|
|
2953
|
+
return found;
|
|
2954
|
+
}
|
|
2955
|
+
}
|
|
2956
|
+
}
|
|
2957
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
2958
|
+
finally {
|
|
2959
|
+
try {
|
|
2960
|
+
if (query_1_1 && !query_1_1.done && (_a = query_1.return)) _a.call(query_1);
|
|
2961
|
+
}
|
|
2962
|
+
finally { if (e_2) throw e_2.error; }
|
|
2963
|
+
}
|
|
2964
|
+
return null;
|
|
2965
|
+
}
|
|
2966
|
+
try {
|
|
2967
|
+
for (var _c = __values(Object.keys(query)), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
2968
|
+
var key = _d.value;
|
|
2969
|
+
if (key.startsWith('$')) {
|
|
2970
|
+
var found = findQueryDateField(query[key]);
|
|
2971
|
+
if (found) {
|
|
2972
|
+
return found;
|
|
2973
|
+
}
|
|
2974
|
+
continue;
|
|
2975
|
+
}
|
|
2976
|
+
if (AI_ASSISTANT_DATE_FALLBACKS[key]) {
|
|
2977
|
+
return key;
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
}
|
|
2981
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
2982
|
+
finally {
|
|
2983
|
+
try {
|
|
2984
|
+
if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
|
|
2985
|
+
}
|
|
2986
|
+
finally { if (e_3) throw e_3.error; }
|
|
2987
|
+
}
|
|
2988
|
+
return null;
|
|
2989
|
+
}
|
|
2990
|
+
function replaceQueryField(query, fromField, toField) {
|
|
2991
|
+
if (Array.isArray(query)) {
|
|
2992
|
+
return query.map(function (entry) { return replaceQueryField(entry, fromField, toField); });
|
|
2993
|
+
}
|
|
2994
|
+
if (!query || typeof query !== 'object' || query instanceof Date) {
|
|
2995
|
+
return query;
|
|
2996
|
+
}
|
|
2997
|
+
var result = {};
|
|
2998
|
+
Object.keys(query).forEach(function (key) {
|
|
2999
|
+
var nextKey = key === fromField ? toField : key;
|
|
3000
|
+
result[nextKey] = replaceQueryField(query[key], fromField, toField);
|
|
3001
|
+
});
|
|
3002
|
+
return result;
|
|
3003
|
+
}
|
|
3004
|
+
function resolveQueryDateFieldFallback(query) {
|
|
3005
|
+
var dateField = findQueryDateField(query);
|
|
3006
|
+
if (!dateField) {
|
|
3007
|
+
return null;
|
|
3008
|
+
}
|
|
3009
|
+
var fallback = AI_ASSISTANT_DATE_FALLBACKS[dateField];
|
|
3010
|
+
if (!fallback) {
|
|
3011
|
+
return null;
|
|
3012
|
+
}
|
|
3013
|
+
return { from: dateField, to: fallback };
|
|
2279
3014
|
}
|
|
2280
3015
|
function containsForbiddenMongoOperators(value) {
|
|
2281
|
-
var
|
|
3016
|
+
var e_4, _a;
|
|
2282
3017
|
if (!value || typeof value !== 'object') {
|
|
2283
3018
|
return false;
|
|
2284
3019
|
}
|
|
@@ -2297,12 +3032,12 @@ function containsForbiddenMongoOperators(value) {
|
|
|
2297
3032
|
}
|
|
2298
3033
|
}
|
|
2299
3034
|
}
|
|
2300
|
-
catch (
|
|
3035
|
+
catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
|
2301
3036
|
finally {
|
|
2302
3037
|
try {
|
|
2303
3038
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
2304
3039
|
}
|
|
2305
|
-
finally { if (
|
|
3040
|
+
finally { if (e_4) throw e_4.error; }
|
|
2306
3041
|
}
|
|
2307
3042
|
return false;
|
|
2308
3043
|
}
|
|
@@ -2465,6 +3200,20 @@ function resolveCodexModel() {
|
|
|
2465
3200
|
|| process.env.AI_DASHBOARD_CODEX_MODEL);
|
|
2466
3201
|
return raw || DEFAULT_CODEX_MODEL;
|
|
2467
3202
|
}
|
|
3203
|
+
function resolveCodexThoughtLevel() {
|
|
3204
|
+
var config = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
|
|
3205
|
+
var raw = normalizeOptionalString(config['AI_ASSISTANT_CODEX_THOUGHT_LEVEL']
|
|
3206
|
+
|| process.env.AI_ASSISTANT_CODEX_THOUGHT_LEVEL
|
|
3207
|
+
|| config['AI_TERMINAL_CODEX_THOUGHT_LEVEL']
|
|
3208
|
+
|| process.env.AI_TERMINAL_CODEX_THOUGHT_LEVEL
|
|
3209
|
+
|| config['AI_DASHBOARD_CODEX_THOUGHT_LEVEL']
|
|
3210
|
+
|| process.env.AI_DASHBOARD_CODEX_THOUGHT_LEVEL);
|
|
3211
|
+
var normalized = (raw || '').trim().toLowerCase();
|
|
3212
|
+
if (normalized === 'minimal' || normalized === 'low' || normalized === 'medium' || normalized === 'high' || normalized === 'xhigh') {
|
|
3213
|
+
return normalized;
|
|
3214
|
+
}
|
|
3215
|
+
return 'low';
|
|
3216
|
+
}
|
|
2468
3217
|
function resolveCodexSettings() {
|
|
2469
3218
|
var serverConfig = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
|
|
2470
3219
|
var apiKey = (serverConfig['OPENAI_API_KEY'] || process.env.OPENAI_API_KEY || '').trim();
|
|
@@ -2522,8 +3271,8 @@ function applyCodexStreamStatusHandler(runOptions, streamStatusHandler) {
|
|
|
2522
3271
|
}
|
|
2523
3272
|
function waitForCodexWorkerMessage(worker, streamStatusHandler) {
|
|
2524
3273
|
return __awaiter(this, void 0, void 0, function () {
|
|
2525
|
-
var _a, _b, _c, _d, message, payload, status_1,
|
|
2526
|
-
var _e,
|
|
3274
|
+
var _a, _b, _c, _d, message, payload, status_1, e_5_1;
|
|
3275
|
+
var _e, e_5, _f, _g;
|
|
2527
3276
|
return __generator(this, function (_h) {
|
|
2528
3277
|
switch (_h.label) {
|
|
2529
3278
|
case 0:
|
|
@@ -2550,8 +3299,8 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
|
|
|
2550
3299
|
return [3 /*break*/, 1];
|
|
2551
3300
|
case 4: return [3 /*break*/, 11];
|
|
2552
3301
|
case 5:
|
|
2553
|
-
|
|
2554
|
-
|
|
3302
|
+
e_5_1 = _h.sent();
|
|
3303
|
+
e_5 = { error: e_5_1 };
|
|
2555
3304
|
return [3 /*break*/, 11];
|
|
2556
3305
|
case 6:
|
|
2557
3306
|
_h.trys.push([6, , 9, 10]);
|
|
@@ -2562,7 +3311,7 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
|
|
|
2562
3311
|
_h.label = 8;
|
|
2563
3312
|
case 8: return [3 /*break*/, 10];
|
|
2564
3313
|
case 9:
|
|
2565
|
-
if (
|
|
3314
|
+
if (e_5) throw e_5.error;
|
|
2566
3315
|
return [7 /*endfinally*/];
|
|
2567
3316
|
case 10: return [7 /*endfinally*/];
|
|
2568
3317
|
case 11: throw new CodexWorkerBootstrapError('Codex worker exited before completing.');
|
|
@@ -2838,6 +3587,43 @@ function resolveAssistantWorkspaceRoot() {
|
|
|
2838
3587
|
});
|
|
2839
3588
|
});
|
|
2840
3589
|
}
|
|
3590
|
+
function isAssistantDataQuestion(message) {
|
|
3591
|
+
var text = normalizeOptionalString(message).toLowerCase();
|
|
3592
|
+
if (!text) {
|
|
3593
|
+
return false;
|
|
3594
|
+
}
|
|
3595
|
+
var patterns = [
|
|
3596
|
+
/\bshow\b/,
|
|
3597
|
+
/\blist\b/,
|
|
3598
|
+
/\bhow many\b/,
|
|
3599
|
+
/\bcount\b/,
|
|
3600
|
+
/\btotal\b/,
|
|
3601
|
+
/\bnumber of\b/,
|
|
3602
|
+
/\blast\b/,
|
|
3603
|
+
/\brecent\b/,
|
|
3604
|
+
/\bthis week\b/,
|
|
3605
|
+
/\blast month\b/,
|
|
3606
|
+
/\boverdue\b/,
|
|
3607
|
+
/\bopen\b/,
|
|
3608
|
+
/\bclosed\b/,
|
|
3609
|
+
/\bcompleted\b/,
|
|
3610
|
+
/\bmissing\b/,
|
|
3611
|
+
/\bgroup(ed)? by\b/,
|
|
3612
|
+
/\bbreakdown\b/,
|
|
3613
|
+
/\bper day\b/,
|
|
3614
|
+
/\bper week\b/,
|
|
3615
|
+
/\bper month\b/
|
|
3616
|
+
];
|
|
3617
|
+
return patterns.some(function (pattern) { return pattern.test(text); });
|
|
3618
|
+
}
|
|
3619
|
+
function buildAssistantCodexDirectivePrompt(message, attachmentText, historyText, contextText) {
|
|
3620
|
+
var trimmedContext = normalizeOptionalString(contextText);
|
|
3621
|
+
var contextBlock = trimmedContext ? "\n\nContext:\n".concat(trimmedContext) : '';
|
|
3622
|
+
var trimmedHistory = normalizeOptionalString(historyText);
|
|
3623
|
+
var historyBlock = trimmedHistory ? "\n\nConversation so far:\n".concat(trimmedHistory) : '';
|
|
3624
|
+
var instruction = '\n\nInstruction:\nReturn ONLY a single MONGO_READ or MONGO_AGG directive line. Do not include any other text.';
|
|
3625
|
+
return "System:\n".concat(AI_ASSISTANT_SYSTEM_PROMPT).concat(contextBlock).concat(historyBlock, "\n\nUser:\n").concat(message).concat(attachmentText || '').concat(instruction).trim();
|
|
3626
|
+
}
|
|
2841
3627
|
function buildAssistantCodexPrompt(message, attachmentText, historyText, contextText) {
|
|
2842
3628
|
var trimmedContext = normalizeOptionalString(contextText);
|
|
2843
3629
|
var contextBlock = trimmedContext ? "\n\nContext:\n".concat(trimmedContext) : '';
|
|
@@ -2871,6 +3657,12 @@ function buildAssistantContext(input, userContext) {
|
|
|
2871
3657
|
if (contextRoute) {
|
|
2872
3658
|
lines.push("Current page route: ".concat(contextRoute));
|
|
2873
3659
|
}
|
|
3660
|
+
var collectionHints = Array.isArray(userContext === null || userContext === void 0 ? void 0 : userContext.collectionHints)
|
|
3661
|
+
? userContext === null || userContext === void 0 ? void 0 : userContext.collectionHints.filter(Boolean)
|
|
3662
|
+
: [];
|
|
3663
|
+
if (collectionHints.length) {
|
|
3664
|
+
lines.push("Collection hints: ".concat(collectionHints.join(', ')));
|
|
3665
|
+
}
|
|
2874
3666
|
var mongoDb = normalizeOptionalString((_c = input === null || input === void 0 ? void 0 : input.mongo) === null || _c === void 0 ? void 0 : _c.database);
|
|
2875
3667
|
var mongoDbs = Array.isArray((_d = input === null || input === void 0 ? void 0 : input.mongo) === null || _d === void 0 ? void 0 : _d.databases)
|
|
2876
3668
|
? input.mongo.databases.map(function (value) { return normalizeOptionalString(value); }).filter(Boolean)
|
|
@@ -2901,7 +3693,7 @@ function normalizeRouteMatchKey(value) {
|
|
|
2901
3693
|
return normalizeRouteKey(value).toLowerCase();
|
|
2902
3694
|
}
|
|
2903
3695
|
function buildClientRouteIndex() {
|
|
2904
|
-
var
|
|
3696
|
+
var e_6, _a;
|
|
2905
3697
|
var _b;
|
|
2906
3698
|
var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
|
|
2907
3699
|
var set = new Set();
|
|
@@ -2920,12 +3712,12 @@ function buildClientRouteIndex() {
|
|
|
2920
3712
|
}
|
|
2921
3713
|
}
|
|
2922
3714
|
}
|
|
2923
|
-
catch (
|
|
3715
|
+
catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
|
2924
3716
|
finally {
|
|
2925
3717
|
try {
|
|
2926
3718
|
if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
|
|
2927
3719
|
}
|
|
2928
|
-
finally { if (
|
|
3720
|
+
finally { if (e_6) throw e_6.error; }
|
|
2929
3721
|
}
|
|
2930
3722
|
return { set: set, map: map, size: routes.length };
|
|
2931
3723
|
}
|
|
@@ -3045,10 +3837,13 @@ function sanitizeAssistantResponse(value) {
|
|
|
3045
3837
|
if (!cleaned) {
|
|
3046
3838
|
return 'I can’t share code, but I can point you to files or explain behavior at a high level.';
|
|
3047
3839
|
}
|
|
3048
|
-
|
|
3840
|
+
var normalizedCurrency = cleaned.replace(/\bUSD\s*([0-9][0-9,]*(?:\.[0-9]+)?)/g, function (_match, amount) {
|
|
3841
|
+
return "$".concat(amount);
|
|
3842
|
+
});
|
|
3843
|
+
return normalizeAssistantRoutes(normalizedCurrency);
|
|
3049
3844
|
}
|
|
3050
3845
|
function evaluateAssistantGuardrails(message) {
|
|
3051
|
-
var
|
|
3846
|
+
var e_7, _a;
|
|
3052
3847
|
var normalized = String(message || '').toLowerCase();
|
|
3053
3848
|
var patterns = [
|
|
3054
3849
|
{
|
|
@@ -3094,12 +3889,12 @@ function evaluateAssistantGuardrails(message) {
|
|
|
3094
3889
|
}
|
|
3095
3890
|
}
|
|
3096
3891
|
}
|
|
3097
|
-
catch (
|
|
3892
|
+
catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
|
3098
3893
|
finally {
|
|
3099
3894
|
try {
|
|
3100
3895
|
if (patterns_1_1 && !patterns_1_1.done && (_a = patterns_1.return)) _a.call(patterns_1);
|
|
3101
3896
|
}
|
|
3102
|
-
finally { if (
|
|
3897
|
+
finally { if (e_7) throw e_7.error; }
|
|
3103
3898
|
}
|
|
3104
3899
|
return null;
|
|
3105
3900
|
}
|
|
@@ -3263,8 +4058,8 @@ function handleCodexUpload(id_conversation, file_name, content_base64, size, con
|
|
|
3263
4058
|
}
|
|
3264
4059
|
function readAttachmentContents(attachments) {
|
|
3265
4060
|
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
|
|
4061
|
+
var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_8_1;
|
|
4062
|
+
var e_8, _b;
|
|
3268
4063
|
return __generator(this, function (_c) {
|
|
3269
4064
|
switch (_c.label) {
|
|
3270
4065
|
case 0:
|
|
@@ -3343,14 +4138,14 @@ function readAttachmentContents(attachments) {
|
|
|
3343
4138
|
return [3 /*break*/, 2];
|
|
3344
4139
|
case 10: return [3 /*break*/, 13];
|
|
3345
4140
|
case 11:
|
|
3346
|
-
|
|
3347
|
-
|
|
4141
|
+
e_8_1 = _c.sent();
|
|
4142
|
+
e_8 = { error: e_8_1 };
|
|
3348
4143
|
return [3 /*break*/, 13];
|
|
3349
4144
|
case 12:
|
|
3350
4145
|
try {
|
|
3351
4146
|
if (attachments_1_1 && !attachments_1_1.done && (_b = attachments_1.return)) _b.call(attachments_1);
|
|
3352
4147
|
}
|
|
3353
|
-
finally { if (
|
|
4148
|
+
finally { if (e_8) throw e_8.error; }
|
|
3354
4149
|
return [7 /*endfinally*/];
|
|
3355
4150
|
case 13: return [2 /*return*/, {
|
|
3356
4151
|
promptText: chunks.length ? "\n\nAttachments:\n".concat(chunks.join('\n\n')) : '',
|
|
@@ -3527,7 +4322,7 @@ function estimateUsage(messages, responseText, model) {
|
|
|
3527
4322
|
};
|
|
3528
4323
|
}
|
|
3529
4324
|
function evaluateGuardrails(message) {
|
|
3530
|
-
var
|
|
4325
|
+
var e_9, _a;
|
|
3531
4326
|
var normalized = String(message || '').toLowerCase();
|
|
3532
4327
|
var patterns = [
|
|
3533
4328
|
{ 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 +4344,12 @@ function evaluateGuardrails(message) {
|
|
|
3549
4344
|
}
|
|
3550
4345
|
}
|
|
3551
4346
|
}
|
|
3552
|
-
catch (
|
|
4347
|
+
catch (e_9_1) { e_9 = { error: e_9_1 }; }
|
|
3553
4348
|
finally {
|
|
3554
4349
|
try {
|
|
3555
4350
|
if (patterns_2_1 && !patterns_2_1.done && (_a = patterns_2.return)) _a.call(patterns_2);
|
|
3556
4351
|
}
|
|
3557
|
-
finally { if (
|
|
4352
|
+
finally { if (e_9) throw e_9.error; }
|
|
3558
4353
|
}
|
|
3559
4354
|
return null;
|
|
3560
4355
|
}
|