@resolveio/server-lib 20.15.8 → 20.16.0

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.
@@ -109,16 +109,21 @@ exports.loadAiTerminalMethods = loadAiTerminalMethods;
109
109
  exports.executeAiAssistantMongoRead = executeAiAssistantMongoRead;
110
110
  exports.executeAiAssistantMongoAggregate = executeAiAssistantMongoAggregate;
111
111
  exports.extractAssistantMongoDirective = extractAssistantMongoDirective;
112
+ exports.normalizeIdsForTargetField = normalizeIdsForTargetField;
112
113
  exports.serializeMongoValue = serializeMongoValue;
113
114
  exports.flattenForTable = flattenForTable;
114
115
  exports.buildDisplayTable = buildDisplayTable;
115
116
  exports.formatDisplayTableMarkdown = formatDisplayTableMarkdown;
117
+ exports.stripQueryFieldPathsDeep = stripQueryFieldPathsDeep;
118
+ exports.stripScopedFieldsFromPipeline = stripScopedFieldsFromPipeline;
119
+ exports.rewriteEmbeddedMatchObjects = rewriteEmbeddedMatchObjects;
116
120
  var fs_1 = require("fs");
117
121
  var events_1 = require("events");
118
122
  var os = require("os");
119
123
  var path = require("path");
120
124
  var promises_1 = require("timers/promises");
121
125
  var worker_threads_1 = require("worker_threads");
126
+ var mongodb_1 = require("mongodb");
122
127
  var simpl_schema_1 = require("simpl-schema");
123
128
  var resolveio_server_app_1 = require("../resolveio-server-app");
124
129
  var user_collection_1 = require("../collections/user.collection");
@@ -142,9 +147,17 @@ var AI_ASSISTANT_TOOL_MAX_STEPS = 1;
142
147
  var AI_ASSISTANT_DISPLAY_MAX_COLUMNS = 12;
143
148
  var AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS = 20;
144
149
  var AI_ASSISTANT_DISPLAY_STRING_LIMIT = 160;
150
+ var AI_ASSISTANT_ID_DISPLAY_LOOKUP_MAX_FIELDS = 4;
151
+ var AI_ASSISTANT_ID_DISPLAY_LOOKUP_MAX_IDS = 60;
152
+ var AI_ASSISTANT_ID_DISPLAY_LOOKUP_MAX_COLLECTIONS = 3;
145
153
  var AI_ASSISTANT_PROGRESS_PLACEHOLDER = 'Planning...';
146
154
  var AI_ASSISTANT_PROGRESS_TICK_MS = 5000;
147
155
  var AI_ASSISTANT_READ_PREFERENCE = 'secondary';
156
+ var AI_ASSISTANT_PROBE_LIMIT = 3;
157
+ var AI_ASSISTANT_COLLECTION_OVERRIDE_SCORE_GAP = 20;
158
+ var AI_ASSISTANT_COLLECTION_OVERRIDE_MIN_SCORE = 20;
159
+ var AI_ASSISTANT_ID_LOOKUP_MAX_RESULTS = 20;
160
+ var AI_ASSISTANT_ID_LOOKUP_CANDIDATE_LIMIT = 4;
148
161
  var AI_ASSISTANT_NAME_MATCH_FALLBACK_MAX_FIELDS = 12;
149
162
  var AI_ASSISTANT_PROGRESS_TICKS = [
150
163
  'Grabbing Data',
@@ -176,6 +189,15 @@ var AI_ASSISTANT_DATE_FALLBACKS = {
176
189
  date_invoice: 'date_invoiced',
177
190
  date_invoiced: 'date_invoice'
178
191
  };
192
+ var AI_ASSISTANT_DATE_EXPANSION_FIELDS = [
193
+ 'date',
194
+ 'date_start',
195
+ 'date_end',
196
+ 'date_original',
197
+ 'date_created',
198
+ 'createdAt',
199
+ 'updatedAt'
200
+ ];
179
201
  var AI_ASSISTANT_BLOCKED_COLLECTIONS = new Set([
180
202
  'user-groups',
181
203
  'logged-in-users',
@@ -202,6 +224,7 @@ var AI_ASSISTANT_SENSITIVE_FIELDS = [
202
224
  'roles'
203
225
  ];
204
226
  var AI_ASSISTANT_CLIENT_SCOPE_CACHE = new Map();
227
+ var AI_ASSISTANT_FIELD_INDEX_CACHE = new Map();
205
228
  var AI_ASSISTANT_COLLECTION_CACHE = new Map();
206
229
  var AI_ASSISTANT_COLLECTION_CACHE_TTL_MS = 5 * 60 * 1000;
207
230
  var AI_ASSISTANT_COLLECTION_STOPWORDS = new Set([
@@ -247,11 +270,72 @@ var AI_ASSISTANT_COLLECTION_STOPWORDS = new Set([
247
270
  'missing',
248
271
  'overdue'
249
272
  ]);
273
+ var AI_ASSISTANT_COLLECTION_DOMAIN_TOKENS = new Set([
274
+ 'blend',
275
+ 'blends',
276
+ 'chemical',
277
+ 'chemicals',
278
+ 'invoice',
279
+ 'invoices',
280
+ 'work',
281
+ 'order',
282
+ 'orders',
283
+ 'delivery',
284
+ 'deliveries',
285
+ 'truck',
286
+ 'treating',
287
+ 'route',
288
+ 'routes',
289
+ 'well',
290
+ 'wells',
291
+ 'sample',
292
+ 'samples',
293
+ 'customer',
294
+ 'customers'
295
+ ]);
296
+ var AI_ASSISTANT_COLLECTION_GENERIC_TOKENS = new Set([
297
+ 'ticket',
298
+ 'tickets',
299
+ 'report',
300
+ 'reports',
301
+ 'summary',
302
+ 'summarize',
303
+ 'recent',
304
+ 'last',
305
+ 'new',
306
+ 'created',
307
+ 'date',
308
+ 'list',
309
+ 'show'
310
+ ]);
311
+ var AI_ASSISTANT_FIELD_TOKEN_SYNONYMS = {
312
+ volume: ['quantity', 'qty', 'amount', 'gallons', 'gallon', 'liters', 'liter', 'litre'],
313
+ quantity: ['volume', 'qty', 'amount', 'gallons', 'gallon'],
314
+ product: ['item', 'chemical', 'material', 'blend', 'name', 'title', 'label'],
315
+ customer: ['client', 'account', 'company'],
316
+ well: ['location', 'site', 'pad', 'api'],
317
+ batch: ['lot'],
318
+ lot: ['batch'],
319
+ date: ['created', 'createdat', 'created_at', 'date_created', 'updated', 'updatedat', 'updated_at', 'date_updated'],
320
+ total: ['sum', 'amount', 'total_amount', 'total_quantity']
321
+ };
322
+ var AI_ASSISTANT_ID_LOOKUP_HINTS = {
323
+ customer: ['customers', 'customer-versions'],
324
+ chemical: ['chemicals', 'chemical-versions'],
325
+ well: ['wells', 'well-groups', 'production-locations', 'locations'],
326
+ location: ['locations', 'production-locations'],
327
+ invoice: ['invoices']
328
+ };
250
329
  var AI_ASSISTANT_TERM_SYNONYMS = [
251
330
  {
252
331
  label: 'truck treating jobs',
253
332
  pattern: /\btruck\s+treating\s+jobs?\b/i,
254
333
  expansions: ['truck treating deliveries', 'truck-treating-deliveries', 'truck treating route events']
334
+ },
335
+ {
336
+ label: 'blend tickets',
337
+ pattern: /\bblend(?:ing)?\s+tickets?\b/i,
338
+ expansions: ['chemical blends', 'chemical-blends', 'report-chemical-blends', 'blend batches']
255
339
  }
256
340
  ];
257
341
  var AI_ASSISTANT_SYSTEM_PROMPT = [
@@ -265,7 +349,9 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
265
349
  '- Do not assist with hacking, bypassing security, or abuse.',
266
350
  'Accuracy & tools:',
267
351
  '- 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.',
352
+ '- Never use *.versions collections for normal requests. Only use a .versions collection when explicitly investigating a bug by checking the last ~5 updates.',
268
353
  '- Planning stage: regex/keyword scan the codebase for collectionName/model definitions, methods, publications, and Angular routes/modules to map user wording to internal names.',
354
+ '- If permissionView starts with /report/, prefer the report-* collection when both report and base collections exist.',
269
355
  '- Map user wording to internal collections/fields yourself. Do not ask for property names unless required to run a query.',
270
356
  '- Use term hints from context (synonym expansions) when mapping user language to collections.',
271
357
  '- 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.',
@@ -273,11 +359,14 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
273
359
  '- For any data request (counts, lists, breakdowns, recent/last items), you MUST run a MONGO_READ or MONGO_AGG before answering.',
274
360
  '- Ask at most one clarifying question only when required to run a query or resolve missing details.',
275
361
  '- 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.',
362
+ '- When resolving id_* fields, prefer lookup definitions from collection schemas/report-builder lookup tables to choose the target collection and name fields.',
276
363
  '- 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.',
277
364
  '- Use the codebase context to choose correct collections/fields/workflows and use MONGO_READ/MONGO_AGG to answer with real data when needed.',
278
365
  '- Process (fast path): Queue -> Planning -> Grabbing Data -> Drafting response. Use regex/keyword matching to identify collections/models, draft a minimal query, run the tool, then format a table. This should be fast; avoid extra narration.',
279
366
  '- Assume a relevant collection exists; if verification reads return zero data, report no data found instead of interrogating the user.',
280
367
  '- Never claim "no data exists" unless you resolved a collection and executed a legitimate query (with fallback date fields when needed) that returned zero rows.',
368
+ '- If a query returns zero rows, run a tiny probe read (limit 1-3) to validate fields and adjust filters/projection before concluding.',
369
+ '- For name-based filters, run a quick existence check with only the date filter first; if records exist, adjust name matching (tokenized regex or ID lookup) instead of concluding no data.',
281
370
  '- For direct questions, answer first. Ask a single follow-up only if required to proceed.',
282
371
  'Data Presentation:',
283
372
  '- Output plain Markdown (NO triple backticks).',
@@ -413,6 +502,12 @@ function drainAssistantCodexRunQueue() {
413
502
  });
414
503
  }
415
504
  function loadAiTerminalMethods(methodManager) {
505
+ var codexWorkerIndex = resolveSingleWorkerTarget(process.env.AI_ASSISTANT_CODEX_WORKER_INDEX
506
+ || process.env.CODEX_WORKER_INDEX
507
+ || process.env.WORKER_CODEX_INDEX);
508
+ var codexWorkerInstance = resolveSingleWorkerTarget(process.env.AI_ASSISTANT_CODEX_WORKER_INSTANCE
509
+ || process.env.CODEX_WORKER_INSTANCE
510
+ || process.env.WORKER_CODEX_INSTANCE);
416
511
  methodManager.methods({
417
512
  aiTerminalConversationCreate: {
418
513
  check: new simpl_schema_1.default({
@@ -644,17 +739,12 @@ function loadAiTerminalMethods(methodManager) {
644
739
  });
645
740
  }
646
741
  },
647
- aiCoderTerminalRunCodex: {
648
- check: new simpl_schema_1.default({
742
+ aiCoderTerminalRunCodex: __assign(__assign(__assign({ check: new simpl_schema_1.default({
649
743
  payload: {
650
744
  type: Object,
651
745
  blackbox: true
652
746
  }
653
- }),
654
- forceWorker: true,
655
- maxConcurrencyPerInstance: 1,
656
- timeoutOverride: resolveCodexTimeoutMs() + 15000,
657
- function: function (payload) {
747
+ }), forceWorker: true, workerQueue: 'codex' }, (codexWorkerIndex ? { targetWorkerIndex: codexWorkerIndex } : {})), (codexWorkerInstance ? { targetWorkerInstance: codexWorkerInstance } : {})), { maxConcurrencyPerInstance: 1, timeoutOverride: resolveCodexTimeoutMs() + 15000, function: function (payload) {
658
748
  return __awaiter(this, void 0, void 0, function () {
659
749
  return __generator(this, function (_a) {
660
750
  switch (_a.label) {
@@ -663,8 +753,7 @@ function loadAiTerminalMethods(methodManager) {
663
753
  }
664
754
  });
665
755
  });
666
- }
667
- },
756
+ } }),
668
757
  aiAssistantMongoRead: {
669
758
  check: new simpl_schema_1.default({
670
759
  payload: {
@@ -1049,10 +1138,10 @@ function executeAiAssistantCodexRun(payload, context) {
1049
1138
  insertResult = _d.sent();
1050
1139
  assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
1051
1140
  enqueueAssistantCodexRun(function () { return __awaiter(_this, void 0, void 0, function () {
1052
- var runStart, steps, recordStep, progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, dataQuestion, lastDirective, toolResponseDebug, toolError, termHints, collectionHints, collectionTokenization, collectionRanking, collectionSelection, timingBreakdown, contextRoute, contextMode, hintSeed, termExpansion, hintText, baseTokens, expandedTokens, dbName, db, collectionNames, _a, assistantContext, prompt_1, workspaceRoot, codexConfig, runOptions, responseText, directiveText, directive, directivePrompt, directiveStart, forcedDirective, _b, initialStart, directivePrompt, forcedStart, forcedDirective, _c, cleanedResponseText, toolRequest, toolStart, toolResponse, _d, toolPayload, followupPrompt, followupStart, followupText, _e, error_2, error_3, finalNow, finishedAt, codexMs, draftingMs, finalMetadata, finalAssistantDoc;
1053
- var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
1054
- return __generator(this, function (_s) {
1055
- switch (_s.label) {
1141
+ var runStart, steps, recordStep, progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, dataQuestion, lastDirective, toolResponseDebug, toolError, termHints, collectionHints, collectionTokenization, collectionRanking, collectionSelection, collectionOverride, collectionNames, timingBreakdown, contextRoute, contextMode, hintSeed, termExpansion, hintText, baseTokens, expandedTokens, baseWeights, expandedWeights, dbName, db, _a, assistantContext, prompt_1, workspaceRoot, codexConfig, runOptions, responseText, directiveText, directive, directivePrompt, directiveStart, forcedDirective, _b, initialStart, directivePrompt, forcedStart, forcedDirective, _c, requestedCollection, cleanedResponseText, effectiveDirective, toolRequest, toolStart, toolResponse, _d, toolPayload, followupPrompt, followupStart, followupText, _e, error_2, error_3, finalNow, finishedAt, codexMs, draftingMs, finalMetadata, finalAssistantDoc;
1142
+ var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
1143
+ return __generator(this, function (_u) {
1144
+ switch (_u.label) {
1056
1145
  case 0:
1057
1146
  runStart = Date.now();
1058
1147
  steps = [];
@@ -1079,6 +1168,8 @@ function executeAiAssistantCodexRun(payload, context) {
1079
1168
  collectionTokenization = null;
1080
1169
  collectionRanking = null;
1081
1170
  collectionSelection = null;
1171
+ collectionOverride = null;
1172
+ collectionNames = [];
1082
1173
  timingBreakdown = {
1083
1174
  directiveMs: 0,
1084
1175
  initialResponseMs: 0,
@@ -1089,37 +1180,42 @@ function executeAiAssistantCodexRun(payload, context) {
1089
1180
  contextRoute = normalizeOptionalString((_f = input === null || input === void 0 ? void 0 : input.context) === null || _f === void 0 ? void 0 : _f.route);
1090
1181
  contextMode = normalizeOptionalString((_g = input === null || input === void 0 ? void 0 : input.context) === null || _g === void 0 ? void 0 : _g.mode);
1091
1182
  recordStep('Queued', { requestId: requestId || undefined });
1092
- _s.label = 1;
1183
+ _u.label = 1;
1093
1184
  case 1:
1094
- _s.trys.push([1, 30, 31, 32]);
1185
+ _u.trys.push([1, 30, 31, 32]);
1095
1186
  hintSeed = [message, contextRoute].filter(Boolean).join(' ');
1096
1187
  termExpansion = expandAssistantTermSynonyms(hintSeed);
1097
1188
  hintText = termExpansion.expanded || hintSeed;
1098
1189
  termHints = termExpansion.matches.map(function (match) { return "".concat(match.term, " -> ").concat(match.expansions.join(', ')); });
1099
1190
  baseTokens = tokenizeCollectionText(hintSeed);
1100
1191
  expandedTokens = tokenizeCollectionText(hintText);
1192
+ baseWeights = computeCollectionTokenWeights(baseTokens);
1193
+ expandedWeights = computeCollectionTokenWeights(expandedTokens);
1101
1194
  collectionTokenization = {
1102
1195
  baseText: hintSeed || undefined,
1103
1196
  expandedText: hintText || undefined,
1104
1197
  baseTokens: baseTokens.length ? baseTokens : undefined,
1105
- expandedTokens: expandedTokens.length ? expandedTokens : undefined
1198
+ expandedTokens: expandedTokens.length ? expandedTokens : undefined,
1199
+ baseTokenWeights: baseTokens.length ? baseWeights.weights : undefined,
1200
+ expandedTokenWeights: expandedTokens.length ? expandedWeights.weights : undefined,
1201
+ hasDomainTokens: expandedTokens.length ? expandedWeights.hasDomain : undefined
1106
1202
  };
1107
1203
  recordStep('Planning: term expansion', {
1108
1204
  termMatches: termExpansion.matches.length ? termExpansion.matches : undefined
1109
1205
  });
1110
- _s.label = 2;
1206
+ _u.label = 2;
1111
1207
  case 2:
1112
- _s.trys.push([2, 4, , 5]);
1208
+ _u.trys.push([2, 4, , 5]);
1113
1209
  dbName = resolveAssistantDatabaseName(undefined, input.mongo);
1114
1210
  db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
1115
1211
  return [4 /*yield*/, listAssistantCollections(db, dbName)];
1116
1212
  case 3:
1117
- collectionNames = _s.sent();
1213
+ collectionNames = _u.sent();
1118
1214
  collectionHints = resolveCollectionHintsFromTokens(expandedTokens, collectionNames, 5);
1119
1215
  collectionRanking = buildCollectionRankingDebugFromTokens(expandedTokens, collectionNames, 8);
1120
1216
  return [3 /*break*/, 5];
1121
1217
  case 4:
1122
- _a = _s.sent();
1218
+ _a = _u.sent();
1123
1219
  collectionHints = [];
1124
1220
  collectionRanking = collectionRanking || ((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens)
1125
1221
  ? buildCollectionRankingDebugFromTokens(collectionTokenization.expandedTokens || [], [], 0)
@@ -1142,7 +1238,7 @@ function executeAiAssistantCodexRun(payload, context) {
1142
1238
  prompt_1 = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1143
1239
  return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
1144
1240
  case 6:
1145
- workspaceRoot = _s.sent();
1241
+ workspaceRoot = _u.sent();
1146
1242
  codexConfig = resolveCodexSettings();
1147
1243
  runOptions = {
1148
1244
  timeoutMs: resolveCodexTimeoutMs(),
@@ -1163,13 +1259,13 @@ function executeAiAssistantCodexRun(payload, context) {
1163
1259
  if (!dataQuestion) return [3 /*break*/, 10];
1164
1260
  recordStep('Directive: determine tool', { type: 'data-question' });
1165
1261
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1166
- _s.label = 7;
1262
+ _u.label = 7;
1167
1263
  case 7:
1168
- _s.trys.push([7, 9, , 10]);
1264
+ _u.trys.push([7, 9, , 10]);
1169
1265
  directiveStart = Date.now();
1170
1266
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1171
1267
  case 8:
1172
- directiveText = _s.sent();
1268
+ directiveText = _u.sent();
1173
1269
  timingBreakdown.directiveMs = Date.now() - directiveStart;
1174
1270
  forcedDirective = extractAssistantMongoDirective(directiveText);
1175
1271
  if (forcedDirective) {
@@ -1186,7 +1282,7 @@ function executeAiAssistantCodexRun(payload, context) {
1186
1282
  }
1187
1283
  return [3 /*break*/, 10];
1188
1284
  case 9:
1189
- _b = _s.sent();
1285
+ _b = _u.sent();
1190
1286
  return [3 /*break*/, 10];
1191
1287
  case 10:
1192
1288
  if (!!directive) return [3 /*break*/, 12];
@@ -1194,7 +1290,7 @@ function executeAiAssistantCodexRun(payload, context) {
1194
1290
  initialStart = Date.now();
1195
1291
  return [4 /*yield*/, runCodexInWorkerThread(prompt_1, runOptions, codexConfig, streamProgress)];
1196
1292
  case 11:
1197
- responseText = _s.sent();
1293
+ responseText = _u.sent();
1198
1294
  timingBreakdown.initialResponseMs = Date.now() - initialStart;
1199
1295
  directive = extractAssistantMongoDirective(responseText);
1200
1296
  if (directive) {
@@ -1208,18 +1304,18 @@ function executeAiAssistantCodexRun(payload, context) {
1208
1304
  permissionView: normalizeOptionalString((_o = directive.payload) === null || _o === void 0 ? void 0 : _o.permissionView) || undefined
1209
1305
  });
1210
1306
  }
1211
- _s.label = 12;
1307
+ _u.label = 12;
1212
1308
  case 12:
1213
1309
  if (!(!directive && dataQuestion)) return [3 /*break*/, 16];
1214
1310
  recordStep('Directive: forced retry', { mode: 'directive-only' });
1215
1311
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1216
- _s.label = 13;
1312
+ _u.label = 13;
1217
1313
  case 13:
1218
- _s.trys.push([13, 15, , 16]);
1314
+ _u.trys.push([13, 15, , 16]);
1219
1315
  forcedStart = Date.now();
1220
1316
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1221
1317
  case 14:
1222
- directiveText = _s.sent();
1318
+ directiveText = _u.sent();
1223
1319
  timingBreakdown.forcedDirectiveMs = Date.now() - forcedStart;
1224
1320
  forcedDirective = extractAssistantMongoDirective(directiveText);
1225
1321
  if (forcedDirective) {
@@ -1236,41 +1332,61 @@ function executeAiAssistantCodexRun(payload, context) {
1236
1332
  }
1237
1333
  return [3 /*break*/, 16];
1238
1334
  case 15:
1239
- _c = _s.sent();
1335
+ _c = _u.sent();
1240
1336
  return [3 /*break*/, 16];
1241
1337
  case 16:
1338
+ if (directive) {
1339
+ requestedCollection = normalizeOptionalString((_s = directive.payload) === null || _s === void 0 ? void 0 : _s.collection);
1340
+ collectionOverride = resolveCollectionOverrideWithContext({
1341
+ message: message,
1342
+ collectionRanking: collectionRanking,
1343
+ requestedCollection: requestedCollection,
1344
+ permissionView: normalizeOptionalString((_t = directive.payload) === null || _t === void 0 ? void 0 : _t.permissionView) || contextRoute,
1345
+ collectionNames: collectionNames
1346
+ });
1347
+ if (collectionOverride) {
1348
+ recordStep('Planning: collection override', {
1349
+ from: collectionOverride.from || undefined,
1350
+ to: collectionOverride.to,
1351
+ reason: collectionOverride.reason,
1352
+ scoreGap: collectionOverride.toScore - collectionOverride.fromScore
1353
+ });
1354
+ }
1355
+ }
1242
1356
  cleanedResponseText = (directive === null || directive === void 0 ? void 0 : directive.cleaned) || responseText;
1243
1357
  if (cleanedResponseText) {
1244
1358
  assistantContent = sanitizeAssistantResponse(cleanedResponseText);
1245
1359
  }
1246
1360
  if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 28];
1247
- toolRequest = buildAssistantToolRequest(directive, input);
1361
+ effectiveDirective = collectionOverride
1362
+ ? __assign(__assign({}, directive), { payload: __assign(__assign({}, (directive.payload || {})), { collection: collectionOverride.to }) }) : directive;
1363
+ toolRequest = buildAssistantToolRequest(effectiveDirective, input);
1248
1364
  progressTracker.push('Grabbing Data');
1249
1365
  recordStep('Grabbing Data: start', {
1250
- type: directive.type,
1366
+ type: effectiveDirective.type,
1251
1367
  collection: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.collection) || undefined,
1252
1368
  permissionView: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.permissionView) || undefined
1253
1369
  });
1254
- _s.label = 17;
1370
+ _u.label = 17;
1255
1371
  case 17:
1256
- _s.trys.push([17, 26, , 27]);
1372
+ _u.trys.push([17, 26, , 27]);
1257
1373
  toolStart = Date.now();
1258
- if (!(directive.type === 'aggregate')) return [3 /*break*/, 19];
1374
+ if (!(effectiveDirective.type === 'aggregate')) return [3 /*break*/, 19];
1259
1375
  return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
1260
1376
  case 18:
1261
- _d = _s.sent();
1377
+ _d = _u.sent();
1262
1378
  return [3 /*break*/, 21];
1263
1379
  case 19: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
1264
1380
  case 20:
1265
- _d = _s.sent();
1266
- _s.label = 21;
1381
+ _d = _u.sent();
1382
+ _u.label = 21;
1267
1383
  case 21:
1268
1384
  toolResponse = _d;
1269
1385
  timingBreakdown.toolMs = Date.now() - toolStart;
1270
1386
  toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
1271
1387
  ? toolResponse.debug
1272
1388
  : null;
1273
- toolPayload = buildAssistantToolResultPayload(directive, toolResponse);
1389
+ toolPayload = buildAssistantToolResultPayload(effectiveDirective, toolResponse);
1274
1390
  toolResult = toolPayload.result;
1275
1391
  recordStep('Grabbing Data: complete', {
1276
1392
  rowCount: toolPayload.result.output.rowCount,
@@ -1280,23 +1396,23 @@ function executeAiAssistantCodexRun(payload, context) {
1280
1396
  progressTracker.push('Drafting response');
1281
1397
  recordStep('Drafting response');
1282
1398
  followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
1283
- _s.label = 22;
1399
+ _u.label = 22;
1284
1400
  case 22:
1285
- _s.trys.push([22, 24, , 25]);
1401
+ _u.trys.push([22, 24, , 25]);
1286
1402
  followupStart = Date.now();
1287
1403
  return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
1288
1404
  case 23:
1289
- followupText = _s.sent();
1405
+ followupText = _u.sent();
1290
1406
  timingBreakdown.followupMs = Date.now() - followupStart;
1291
1407
  assistantContent = sanitizeAssistantResponse(followupText);
1292
1408
  return [3 /*break*/, 25];
1293
1409
  case 24:
1294
- _e = _s.sent();
1410
+ _e = _u.sent();
1295
1411
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
1296
1412
  return [3 /*break*/, 25];
1297
1413
  case 25: return [3 /*break*/, 27];
1298
1414
  case 26:
1299
- error_2 = _s.sent();
1415
+ error_2 = _u.sent();
1300
1416
  assistantContent = buildAssistantToolErrorMessage(error_2, directive, toolRequest);
1301
1417
  toolError = error_2;
1302
1418
  return [3 /*break*/, 27];
@@ -1304,10 +1420,10 @@ function executeAiAssistantCodexRun(payload, context) {
1304
1420
  case 28:
1305
1421
  progressTracker.push('Drafting response');
1306
1422
  recordStep('Drafting response');
1307
- _s.label = 29;
1423
+ _u.label = 29;
1308
1424
  case 29: return [3 /*break*/, 32];
1309
1425
  case 30:
1310
- error_3 = _s.sent();
1426
+ error_3 = _u.sent();
1311
1427
  assistantContent = buildAssistantCodexErrorMessage(error_3);
1312
1428
  recordStep('Error', { message: normalizeOptionalString(error_3 === null || error_3 === void 0 ? void 0 : error_3.message) || 'Unknown error' });
1313
1429
  return [3 /*break*/, 32];
@@ -1333,6 +1449,7 @@ function executeAiAssistantCodexRun(payload, context) {
1333
1449
  toolResult: toolResult,
1334
1450
  toolResponseDebug: toolResponseDebug,
1335
1451
  toolError: toolError,
1452
+ collectionOverride: collectionOverride,
1336
1453
  trace: {
1337
1454
  steps: steps,
1338
1455
  planning: {
@@ -1342,7 +1459,8 @@ function executeAiAssistantCodexRun(payload, context) {
1342
1459
  collectionHints: collectionHints.length ? collectionHints : undefined,
1343
1460
  collectionTokenization: collectionTokenization || undefined,
1344
1461
  collectionRanking: collectionRanking || undefined,
1345
- collectionSelection: collectionSelection || undefined
1462
+ collectionSelection: collectionSelection || undefined,
1463
+ collectionOverride: collectionOverride || undefined
1346
1464
  },
1347
1465
  timings: {
1348
1466
  startedAt: new Date(runStart).toISOString(),
@@ -1370,16 +1488,16 @@ function executeAiAssistantCodexRun(payload, context) {
1370
1488
  }
1371
1489
  })];
1372
1490
  case 33:
1373
- _s.sent();
1374
- _s.label = 34;
1491
+ _u.sent();
1492
+ _u.label = 34;
1375
1493
  case 34: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
1376
1494
  case 35:
1377
- _s.sent();
1495
+ _u.sent();
1378
1496
  if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 37];
1379
1497
  return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
1380
1498
  case 36:
1381
- _s.sent();
1382
- _s.label = 37;
1499
+ _u.sent();
1500
+ _u.label = 37;
1383
1501
  case 37: return [2 /*return*/, finalAssistantDoc];
1384
1502
  }
1385
1503
  });
@@ -1393,10 +1511,10 @@ function executeAiAssistantCodexRun(payload, context) {
1393
1511
  }
1394
1512
  function executeAiAssistantMongoRead(payload, context) {
1395
1513
  return __awaiter(this, void 0, void 0, function () {
1396
- 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, expanded, fallbackDocs, total, sanitizedDocuments, includeIds, requestedFields, fieldAliases, displayDocs, priorityFields, display;
1397
- var _c, _d;
1398
- return __generator(this, function (_e) {
1399
- switch (_e.label) {
1514
+ var input, rawCollection, dbName, db, collectionResolution, collection, schemaFields, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, strippedClient, clientScopedQuery, scopedQuery, normalized, findOptions, documents, executedQuery, probeDocs, dateFallback, fallbackQuery, fallbackDocs, expanded, fallbackDocs, nameFallback, fallbackDocs, _c, chemicalLookup, fallbackDocs, queryFields, _d, aliases, rewrittenQuery, fallbackDocs, _e, idLookup, fallbackDocs, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, nameFields, dateFields, diagnostics, queryNoName, _f, queryNoDate, _g, _h, _j, _k, allCollections, base, alt, altCount, _l, total, sanitizedDocuments, requestedFields, missingFields, _m, projectionAliases, expandedProjection, refreshedDocs, includeIds, fieldAliases, displayDocs, idLookupDisplay, priorityFields, display;
1515
+ var _o, _p;
1516
+ return __generator(this, function (_q) {
1517
+ switch (_q.label) {
1400
1518
  case 0:
1401
1519
  input = payload || {};
1402
1520
  rawCollection = normalizeOptionalString(input.collection);
@@ -1407,16 +1525,27 @@ function executeAiAssistantMongoRead(payload, context) {
1407
1525
  db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
1408
1526
  return [4 /*yield*/, resolveAssistantCollectionName(db, dbName, rawCollection)];
1409
1527
  case 1:
1410
- collectionResolution = _e.sent();
1528
+ collectionResolution = _q.sent();
1411
1529
  collection = collectionResolution.name || rawCollection;
1530
+ schemaFields = getCollectionSchemaFieldNames(collection);
1412
1531
  return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
1413
1532
  case 2:
1414
- _a = _e.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
1533
+ _a = _q.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
1415
1534
  if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
1416
1535
  throw new Error('AI assistant mongo read: Access denied.');
1417
1536
  }
1418
- customerId = normalizeOptionalString((_c = user === null || user === void 0 ? void 0 : user.other) === null || _c === void 0 ? void 0 : _c.id_customer);
1537
+ customerId = normalizeOptionalString((_o = user === null || user === void 0 ? void 0 : user.other) === null || _o === void 0 ? void 0 : _o.id_customer);
1538
+ fallbackMeta = {};
1419
1539
  baseQuery = normalizeMongoQuery(input.query);
1540
+ if (!isSuperAdmin && customerId) {
1541
+ stripped = stripQueryFieldPathsDeepWithMeta(baseQuery, ['id_customer', 'other.id_customer']);
1542
+ baseQuery = stripped.value;
1543
+ fallbackMeta.scopeStrip = {
1544
+ attempted: true,
1545
+ fields: ['id_customer', 'other.id_customer'],
1546
+ used: stripped.changed
1547
+ };
1548
+ }
1420
1549
  if (!isSuperAdmin && (collection === 'users' || collection === 'user-versions')) {
1421
1550
  userId = normalizeOptionalString(user === null || user === void 0 ? void 0 : user._id);
1422
1551
  if (!userId) {
@@ -1430,13 +1559,22 @@ function executeAiAssistantMongoRead(payload, context) {
1430
1559
  if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 4];
1431
1560
  return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
1432
1561
  case 3:
1433
- _b = _e.sent();
1562
+ _b = _q.sent();
1434
1563
  return [3 /*break*/, 5];
1435
1564
  case 4:
1436
1565
  _b = false;
1437
- _e.label = 5;
1566
+ _q.label = 5;
1438
1567
  case 5:
1439
1568
  shouldScopeByClient = _b;
1569
+ if (!isSuperAdmin && shouldScopeByClient) {
1570
+ strippedClient = stripQueryFieldPathsDeepWithMeta(baseQuery, ['id_client']);
1571
+ baseQuery = strippedClient.value;
1572
+ fallbackMeta.scopeStripClient = {
1573
+ attempted: true,
1574
+ fields: ['id_client'],
1575
+ used: strippedClient.changed
1576
+ };
1577
+ }
1440
1578
  clientScopedQuery = shouldScopeByClient
1441
1579
  ? applyClientScopeFilter(baseQuery, normalizedClient, isSuperAdmin)
1442
1580
  : baseQuery;
@@ -1445,26 +1583,26 @@ function executeAiAssistantMongoRead(payload, context) {
1445
1583
  findOptions = __assign(__assign({}, normalized.findOptions), { readPreference: AI_ASSISTANT_READ_PREFERENCE });
1446
1584
  return [4 /*yield*/, db.collection(collection).find(scopedQuery, findOptions).toArray()];
1447
1585
  case 6:
1448
- documents = _e.sent();
1586
+ documents = _q.sent();
1449
1587
  executedQuery = scopedQuery;
1450
- fallbackMeta = {};
1451
- if (!!documents.length) return [3 /*break*/, 10];
1588
+ probeDocs = null;
1589
+ if (!!documents.length) return [3 /*break*/, 8];
1452
1590
  dateFallback = resolveQueryDateFieldFallback(scopedQuery);
1453
1591
  if (!dateFallback) return [3 /*break*/, 8];
1454
1592
  fallbackQuery = replaceQueryField(scopedQuery, dateFallback.from, dateFallback.to);
1455
1593
  fallbackMeta.dateField = __assign(__assign({}, dateFallback), { attempted: true, used: false });
1456
1594
  return [4 /*yield*/, db.collection(collection).find(fallbackQuery, findOptions).toArray()];
1457
1595
  case 7:
1458
- fallbackDocs = _e.sent();
1596
+ fallbackDocs = _q.sent();
1459
1597
  if (fallbackDocs.length) {
1460
1598
  documents = fallbackDocs;
1461
1599
  executedQuery = fallbackQuery;
1462
1600
  fallbackMeta.dateField.used = true;
1463
1601
  }
1464
- _e.label = 8;
1602
+ _q.label = 8;
1465
1603
  case 8:
1466
1604
  if (!!documents.length) return [3 /*break*/, 10];
1467
- expanded = expandQueryDateFallbacks(scopedQuery);
1605
+ expanded = expandQueryDateFallbacks(executedQuery);
1468
1606
  if (!expanded) return [3 /*break*/, 10];
1469
1607
  fallbackMeta.dateFieldsExpanded = {
1470
1608
  fields: expanded.fields,
@@ -1473,30 +1611,334 @@ function executeAiAssistantMongoRead(payload, context) {
1473
1611
  };
1474
1612
  return [4 /*yield*/, db.collection(collection).find(expanded.query, findOptions).toArray()];
1475
1613
  case 9:
1476
- fallbackDocs = _e.sent();
1614
+ fallbackDocs = _q.sent();
1477
1615
  if (fallbackDocs.length) {
1478
1616
  documents = fallbackDocs;
1479
1617
  executedQuery = expanded.query;
1480
1618
  fallbackMeta.dateFieldsExpanded.used = true;
1481
1619
  }
1482
- _e.label = 10;
1620
+ _q.label = 10;
1483
1621
  case 10:
1484
- total = null;
1485
- if (!normalized.includeTotal) return [3 /*break*/, 12];
1486
- return [4 /*yield*/, db.collection(collection).countDocuments(executedQuery, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
1622
+ if (!!documents.length) return [3 /*break*/, 12];
1623
+ nameFallback = resolveReadNameMatchFallback(executedQuery);
1624
+ if (!nameFallback) return [3 /*break*/, 12];
1625
+ fallbackMeta.nameMatch = {
1626
+ field: nameFallback.field,
1627
+ fields: nameFallback.fields,
1628
+ attempted: true,
1629
+ used: false
1630
+ };
1631
+ return [4 /*yield*/, db.collection(collection).find(nameFallback.query, findOptions).toArray()];
1487
1632
  case 11:
1488
- total = _e.sent();
1489
- _e.label = 12;
1633
+ fallbackDocs = _q.sent();
1634
+ if (fallbackDocs.length) {
1635
+ documents = fallbackDocs;
1636
+ executedQuery = nameFallback.query;
1637
+ fallbackMeta.nameMatch.used = true;
1638
+ }
1639
+ _q.label = 12;
1490
1640
  case 12:
1641
+ if (!!documents.length) return [3 /*break*/, 17];
1642
+ _c = probeDocs;
1643
+ if (_c) return [3 /*break*/, 14];
1644
+ return [4 /*yield*/, fetchAssistantProbeDocs({
1645
+ db: db,
1646
+ collection: collection,
1647
+ idClient: normalizedClient,
1648
+ idCustomer: customerId,
1649
+ isSuperAdmin: isSuperAdmin,
1650
+ includeClientScope: shouldScopeByClient
1651
+ })];
1652
+ case 13:
1653
+ _c = (_q.sent());
1654
+ _q.label = 14;
1655
+ case 14:
1656
+ probeDocs = _c;
1657
+ return [4 /*yield*/, applyChemicalNameLookupFallbackToQuery({
1658
+ query: executedQuery,
1659
+ db: db,
1660
+ dbName: dbName,
1661
+ idClient: normalizedClient,
1662
+ idCustomer: customerId,
1663
+ isSuperAdmin: isSuperAdmin,
1664
+ probeDocs: probeDocs || undefined
1665
+ })];
1666
+ case 15:
1667
+ chemicalLookup = _q.sent();
1668
+ if (!chemicalLookup) return [3 /*break*/, 17];
1669
+ fallbackMeta.chemicalLookup = __assign(__assign({}, chemicalLookup.meta), { attempted: true, used: false });
1670
+ return [4 /*yield*/, db.collection(collection).find(chemicalLookup.query, findOptions).toArray()];
1671
+ case 16:
1672
+ fallbackDocs = _q.sent();
1673
+ if (fallbackDocs.length) {
1674
+ documents = fallbackDocs;
1675
+ executedQuery = chemicalLookup.query;
1676
+ fallbackMeta.chemicalLookup.used = true;
1677
+ }
1678
+ _q.label = 17;
1679
+ case 17:
1680
+ if (!!documents.length) return [3 /*break*/, 21];
1681
+ queryFields = extractQueryFieldPaths(executedQuery).filter(function (field) { return !isAssistantIdField(field); });
1682
+ if (!queryFields.length) return [3 /*break*/, 21];
1683
+ _d = probeDocs;
1684
+ if (_d) return [3 /*break*/, 19];
1685
+ return [4 /*yield*/, fetchAssistantProbeDocs({
1686
+ db: db,
1687
+ collection: collection,
1688
+ idClient: normalizedClient,
1689
+ idCustomer: customerId,
1690
+ isSuperAdmin: isSuperAdmin,
1691
+ includeClientScope: shouldScopeByClient
1692
+ })];
1693
+ case 18:
1694
+ _d = (_q.sent());
1695
+ _q.label = 19;
1696
+ case 19:
1697
+ probeDocs = _d;
1698
+ if (!probeDocs.length) return [3 /*break*/, 21];
1699
+ aliases = resolveFieldAliases(probeDocs, queryFields, schemaFields);
1700
+ if (!Object.keys(aliases).length) return [3 /*break*/, 21];
1701
+ fallbackMeta.queryFieldAliases = {
1702
+ aliases: aliases,
1703
+ attempted: true,
1704
+ used: false
1705
+ };
1706
+ rewrittenQuery = Object.entries(aliases)
1707
+ .reduce(function (acc, _a) {
1708
+ var _b = __read(_a, 2), from = _b[0], to = _b[1];
1709
+ return replaceFieldPathDeep(acc, from, to);
1710
+ }, executedQuery);
1711
+ return [4 /*yield*/, db.collection(collection).find(rewrittenQuery, findOptions).toArray()];
1712
+ case 20:
1713
+ fallbackDocs = _q.sent();
1714
+ if (fallbackDocs.length) {
1715
+ documents = fallbackDocs;
1716
+ executedQuery = rewrittenQuery;
1717
+ fallbackMeta.queryFieldAliases.used = true;
1718
+ }
1719
+ _q.label = 21;
1720
+ case 21:
1721
+ if (!!documents.length) return [3 /*break*/, 26];
1722
+ _e = probeDocs;
1723
+ if (_e) return [3 /*break*/, 23];
1724
+ return [4 /*yield*/, fetchAssistantProbeDocs({
1725
+ db: db,
1726
+ collection: collection,
1727
+ idClient: normalizedClient,
1728
+ idCustomer: customerId,
1729
+ isSuperAdmin: isSuperAdmin,
1730
+ includeClientScope: shouldScopeByClient
1731
+ })];
1732
+ case 22:
1733
+ _e = (_q.sent());
1734
+ _q.label = 23;
1735
+ case 23:
1736
+ probeDocs = _e;
1737
+ return [4 /*yield*/, applyIdLookupFallbackToQuery({
1738
+ query: executedQuery,
1739
+ db: db,
1740
+ dbName: dbName,
1741
+ idClient: normalizedClient,
1742
+ idCustomer: customerId,
1743
+ isSuperAdmin: isSuperAdmin,
1744
+ probeDocs: probeDocs || undefined
1745
+ })];
1746
+ case 24:
1747
+ idLookup = _q.sent();
1748
+ if (!idLookup) return [3 /*break*/, 26];
1749
+ fallbackMeta.idLookup = __assign(__assign({}, idLookup.meta), { attempted: true, used: false });
1750
+ return [4 /*yield*/, db.collection(collection).find(idLookup.query, findOptions).toArray()];
1751
+ case 25:
1752
+ fallbackDocs = _q.sent();
1753
+ if (fallbackDocs.length) {
1754
+ documents = fallbackDocs;
1755
+ executedQuery = idLookup.query;
1756
+ fallbackMeta.idLookup.used = true;
1757
+ }
1758
+ _q.label = 26;
1759
+ case 26:
1760
+ if (!!documents.length) return [3 /*break*/, 29];
1761
+ return [4 /*yield*/, resolveBaseCollectionFromReport(db, dbName, collection)];
1762
+ case 27:
1763
+ baseCollection = _q.sent();
1764
+ if (!(baseCollection && baseCollection !== collection)) return [3 /*break*/, 29];
1765
+ fallbackPayload = __assign(__assign({}, input), { collection: baseCollection });
1766
+ return [4 /*yield*/, executeAiAssistantMongoRead(fallbackPayload, context)];
1767
+ case 28:
1768
+ fallbackResult = _q.sent();
1769
+ if (Array.isArray(fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.documents) && fallbackResult.documents.length) {
1770
+ if (isSuperAdmin && (fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.debug) && typeof fallbackResult.debug === 'object') {
1771
+ existingFallbacks = fallbackResult.debug.fallbacks && typeof fallbackResult.debug.fallbacks === 'object'
1772
+ ? fallbackResult.debug.fallbacks
1773
+ : {};
1774
+ fallbackResult.debug.fallbacks = __assign(__assign({}, existingFallbacks), { reportFallback: {
1775
+ from: collection,
1776
+ to: baseCollection,
1777
+ used: true
1778
+ } });
1779
+ }
1780
+ return [2 /*return*/, fallbackResult];
1781
+ }
1782
+ if (isSuperAdmin) {
1783
+ fallbackMeta.reportFallback = { from: collection, to: baseCollection, attempted: true, used: false };
1784
+ }
1785
+ _q.label = 29;
1786
+ case 29:
1787
+ if (!(!documents.length && isSuperAdmin)) return [3 /*break*/, 46];
1788
+ nameFields = collectMatchFieldsByCondition(executedQuery, function (field, condition) { return isRegexMatchCondition(condition)
1789
+ || (typeof condition === 'string' && shouldApplyAssistantNameRegex(field)); });
1790
+ dateFields = collectMatchFieldsByCondition(executedQuery, function (_field, condition) { return isDateCondition(condition); });
1791
+ diagnostics = {
1792
+ nameFields: nameFields.length ? nameFields : undefined,
1793
+ dateFields: dateFields.length ? dateFields : undefined
1794
+ };
1795
+ _q.label = 30;
1796
+ case 30:
1797
+ _q.trys.push([30, 35, , 36]);
1798
+ if (!nameFields.length) return [3 /*break*/, 32];
1799
+ queryNoName = stripMatchFields(executedQuery, nameFields);
1800
+ _f = diagnostics;
1801
+ return [4 /*yield*/, db.collection(collection).countDocuments(queryNoName, {
1802
+ readPreference: AI_ASSISTANT_READ_PREFERENCE
1803
+ })];
1804
+ case 31:
1805
+ _f.recentCount = _q.sent();
1806
+ _q.label = 32;
1807
+ case 32:
1808
+ if (!dateFields.length) return [3 /*break*/, 34];
1809
+ queryNoDate = stripMatchFields(executedQuery, dateFields);
1810
+ _g = diagnostics;
1811
+ return [4 /*yield*/, db.collection(collection).countDocuments(queryNoDate, {
1812
+ readPreference: AI_ASSISTANT_READ_PREFERENCE
1813
+ })];
1814
+ case 33:
1815
+ _g.nameMatchCount = _q.sent();
1816
+ _q.label = 34;
1817
+ case 34: return [3 /*break*/, 36];
1818
+ case 35:
1819
+ _h = _q.sent();
1820
+ return [3 /*break*/, 36];
1821
+ case 36:
1822
+ _q.trys.push([36, 39, , 40]);
1823
+ _j = probeDocs;
1824
+ if (_j) return [3 /*break*/, 38];
1825
+ return [4 /*yield*/, fetchAssistantProbeDocs({
1826
+ db: db,
1827
+ collection: collection,
1828
+ idClient: normalizedClient,
1829
+ idCustomer: customerId,
1830
+ isSuperAdmin: isSuperAdmin,
1831
+ includeClientScope: shouldScopeByClient
1832
+ })];
1833
+ case 37:
1834
+ _j = (_q.sent());
1835
+ _q.label = 38;
1836
+ case 38:
1837
+ probeDocs = _j;
1838
+ if (probeDocs.length && nameFields.length) {
1839
+ diagnostics.chemicalIdDetected = detectChemicalIdFromProbe(probeDocs, nameFields);
1840
+ }
1841
+ return [3 /*break*/, 40];
1842
+ case 39:
1843
+ _k = _q.sent();
1844
+ return [3 /*break*/, 40];
1845
+ case 40:
1846
+ _q.trys.push([40, 44, , 45]);
1847
+ return [4 /*yield*/, listAssistantCollections(db, dbName)];
1848
+ case 41:
1849
+ allCollections = _q.sent();
1850
+ base = stripVersionSuffix(collection.startsWith('report-') ? collection.slice('report-'.length) : collection);
1851
+ alt = collection.startsWith('report-') ? base : "report-".concat(base);
1852
+ if (!(alt && alt !== collection && allCollections.includes(alt))) return [3 /*break*/, 43];
1853
+ return [4 /*yield*/, db.collection(alt).countDocuments({}, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
1854
+ case 42:
1855
+ altCount = _q.sent();
1856
+ diagnostics.alternateCollection = alt;
1857
+ diagnostics.alternateCollectionCount = altCount;
1858
+ _q.label = 43;
1859
+ case 43: return [3 /*break*/, 45];
1860
+ case 44:
1861
+ _l = _q.sent();
1862
+ return [3 /*break*/, 45];
1863
+ case 45:
1864
+ fallbackMeta.zeroDiagnostics = diagnostics;
1865
+ _q.label = 46;
1866
+ case 46:
1867
+ total = null;
1868
+ if (!normalized.includeTotal) return [3 /*break*/, 48];
1869
+ return [4 /*yield*/, db.collection(collection).countDocuments(executedQuery, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
1870
+ case 47:
1871
+ total = _q.sent();
1872
+ _q.label = 48;
1873
+ case 48:
1491
1874
  sanitizedDocuments = isSuperAdmin
1492
1875
  ? documents
1493
1876
  : documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
1494
- includeIds = ((_d = input.options) === null || _d === void 0 ? void 0 : _d.includeIds) === true;
1495
- requestedFields = resolveProjectionRequestedFields(normalized.findOptions.projection);
1496
- fieldAliases = resolveFieldAliases(sanitizedDocuments, requestedFields);
1877
+ requestedFields = resolveProjectionRequestedFields(findOptions.projection);
1878
+ if (!(sanitizedDocuments.length && requestedFields.length)) return [3 /*break*/, 52];
1879
+ missingFields = requestedFields.filter(function (field) { return !hasNonEmptyValue(sanitizedDocuments, field, { treatObjectLikeAsEmpty: true }); });
1880
+ if (!missingFields.length) return [3 /*break*/, 52];
1881
+ _m = probeDocs;
1882
+ if (_m) return [3 /*break*/, 50];
1883
+ return [4 /*yield*/, fetchAssistantProbeDocs({
1884
+ db: db,
1885
+ collection: collection,
1886
+ idClient: normalizedClient,
1887
+ idCustomer: customerId,
1888
+ isSuperAdmin: isSuperAdmin,
1889
+ includeClientScope: shouldScopeByClient
1890
+ })];
1891
+ case 49:
1892
+ _m = (_q.sent());
1893
+ _q.label = 50;
1894
+ case 50:
1895
+ probeDocs = _m;
1896
+ if (!probeDocs.length) return [3 /*break*/, 52];
1897
+ projectionAliases = resolveFieldAliases(probeDocs, missingFields, schemaFields);
1898
+ if (!Object.keys(projectionAliases).length) return [3 /*break*/, 52];
1899
+ fallbackMeta.projectionAliases = {
1900
+ aliases: projectionAliases,
1901
+ attempted: true,
1902
+ used: false
1903
+ };
1904
+ expandedProjection = expandProjectionWithAliases(findOptions.projection, projectionAliases);
1905
+ if (!(expandedProjection && expandedProjection !== findOptions.projection)) return [3 /*break*/, 52];
1906
+ findOptions = __assign(__assign({}, findOptions), { projection: expandedProjection });
1907
+ normalized.findOptions.projection = expandedProjection;
1908
+ return [4 /*yield*/, db.collection(collection).find(executedQuery, findOptions).toArray()];
1909
+ case 51:
1910
+ refreshedDocs = _q.sent();
1911
+ if (refreshedDocs.length) {
1912
+ documents = refreshedDocs;
1913
+ sanitizedDocuments = isSuperAdmin
1914
+ ? refreshedDocs
1915
+ : refreshedDocs.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
1916
+ fallbackMeta.projectionAliases.used = true;
1917
+ }
1918
+ _q.label = 52;
1919
+ case 52:
1920
+ includeIds = ((_p = input.options) === null || _p === void 0 ? void 0 : _p.includeIds) === true;
1921
+ fieldAliases = resolveFieldAliases(sanitizedDocuments, requestedFields, schemaFields);
1497
1922
  displayDocs = Object.keys(fieldAliases).length
1498
1923
  ? applyFieldAliasesForDisplay(sanitizedDocuments, fieldAliases)
1499
1924
  : sanitizedDocuments;
1925
+ return [4 /*yield*/, applyIdLookupDisplayEnrichment({
1926
+ docs: displayDocs,
1927
+ collection: collection,
1928
+ db: db,
1929
+ dbName: dbName,
1930
+ idClient: normalizedClient,
1931
+ idCustomer: customerId,
1932
+ isSuperAdmin: isSuperAdmin
1933
+ })];
1934
+ case 53:
1935
+ idLookupDisplay = _q.sent();
1936
+ if (idLookupDisplay === null || idLookupDisplay === void 0 ? void 0 : idLookupDisplay.docs) {
1937
+ displayDocs = idLookupDisplay.docs;
1938
+ }
1939
+ if (idLookupDisplay === null || idLookupDisplay === void 0 ? void 0 : idLookupDisplay.meta) {
1940
+ fallbackMeta.idDisplayLookup = idLookupDisplay.meta;
1941
+ }
1500
1942
  priorityFields = requestedFields.length
1501
1943
  ? __spreadArray(__spreadArray([], __read(requestedFields), false), __read(AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS), false) : AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS;
1502
1944
  display = buildDisplayTable(displayDocs, {
@@ -1533,10 +1975,10 @@ function executeAiAssistantMongoRead(payload, context) {
1533
1975
  }
1534
1976
  function executeAiAssistantMongoAggregate(payload, context) {
1535
1977
  return __awaiter(this, void 0, void 0, function () {
1536
- 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, completionExprFallback, fallbackPipeline, fallbackDocs, unwindFallback, fallbackPipeline, fallbackDocs, nameFallback, fallbackPipeline, fallbackDocs, sanitizedDocuments, includeIds, display;
1537
- var _c, _d;
1538
- return __generator(this, function (_e) {
1539
- switch (_e.label) {
1978
+ var input, rawCollection, dbName, db, collectionResolution, collection, schemaFields, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, sanitizedPipeline, strippedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, dateField, aggregateOptions, documents, executedPipeline, probeDocs, fallback, fallbackPipeline, fallbackDocs, createdFallback, createdPipeline, createdDocs, expanded, expandedDocs, completionFallback, fallbackPipeline, fallbackDocs, completionExprFallback, fallbackPipeline, fallbackDocs, unwindFallback, fallbackPipeline, fallbackDocs, nameFallback, fallbackPipeline, fallbackDocs, _c, _loop_1, i, state_1, matchFields_1, _d, aliases, rewrittenPipeline, fallbackDocs, _loop_2, i, state_2, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, matchStages, diagnostics, combinedMatch, nameFields, dateFields, queryNoName, _e, queryNoDate, _f, _g, _h, _j, allCollections, base, alt, altCount, _k, sanitizedDocuments, includeIds, displayDocs, idLookupDisplay, display;
1979
+ var _l, _m;
1980
+ return __generator(this, function (_o) {
1981
+ switch (_o.label) {
1540
1982
  case 0:
1541
1983
  input = payload || {};
1542
1984
  rawCollection = normalizeOptionalString(input.collection);
@@ -1547,16 +1989,27 @@ function executeAiAssistantMongoAggregate(payload, context) {
1547
1989
  db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
1548
1990
  return [4 /*yield*/, resolveAssistantCollectionName(db, dbName, rawCollection)];
1549
1991
  case 1:
1550
- collectionResolution = _e.sent();
1992
+ collectionResolution = _o.sent();
1551
1993
  collection = collectionResolution.name || rawCollection;
1994
+ schemaFields = getCollectionSchemaFieldNames(collection);
1552
1995
  return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
1553
1996
  case 2:
1554
- _a = _e.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
1997
+ _a = _o.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
1555
1998
  if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
1556
1999
  throw new Error('AI assistant mongo aggregate: Access denied.');
1557
2000
  }
1558
- customerId = normalizeOptionalString((_c = user === null || user === void 0 ? void 0 : user.other) === null || _c === void 0 ? void 0 : _c.id_customer);
2001
+ customerId = normalizeOptionalString((_l = user === null || user === void 0 ? void 0 : user.other) === null || _l === void 0 ? void 0 : _l.id_customer);
2002
+ fallbackMeta = {};
1559
2003
  baseQuery = normalizeMongoQuery(input.query);
2004
+ if (!isSuperAdmin && customerId) {
2005
+ stripped = stripQueryFieldPathsDeepWithMeta(baseQuery, ['id_customer', 'other.id_customer']);
2006
+ baseQuery = stripped.value;
2007
+ fallbackMeta.scopeStrip = {
2008
+ attempted: true,
2009
+ fields: ['id_customer', 'other.id_customer'],
2010
+ used: stripped.changed
2011
+ };
2012
+ }
1560
2013
  if (!isSuperAdmin && (collection === 'users' || collection === 'user-versions')) {
1561
2014
  userId = normalizeOptionalString(user === null || user === void 0 ? void 0 : user._id);
1562
2015
  if (!userId) {
@@ -1570,11 +2023,11 @@ function executeAiAssistantMongoAggregate(payload, context) {
1570
2023
  if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 4];
1571
2024
  return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
1572
2025
  case 3:
1573
- _b = _e.sent();
2026
+ _b = _o.sent();
1574
2027
  return [3 /*break*/, 5];
1575
2028
  case 4:
1576
2029
  _b = false;
1577
- _e.label = 5;
2030
+ _o.label = 5;
1578
2031
  case 5:
1579
2032
  shouldScopeByClient = _b;
1580
2033
  clientScopedQuery = shouldScopeByClient
@@ -1582,7 +2035,17 @@ function executeAiAssistantMongoAggregate(payload, context) {
1582
2035
  : baseQuery;
1583
2036
  scopedQuery = applyCustomerScopeFilter(clientScopedQuery, collection, customerId, isSuperAdmin);
1584
2037
  normalizedPipeline = normalizeAssistantAggregatePipeline(input.pipeline);
1585
- pipelineWithScope = buildAssistantAggregatePipeline(scopedQuery, normalizedPipeline);
2038
+ sanitizedPipeline = normalizedPipeline;
2039
+ if (!isSuperAdmin && customerId) {
2040
+ strippedPipeline = stripScopedFieldsFromPipelineWithMeta(normalizedPipeline, ['id_customer', 'other.id_customer']);
2041
+ sanitizedPipeline = strippedPipeline.pipeline;
2042
+ fallbackMeta.scopeStripPipeline = {
2043
+ attempted: true,
2044
+ fields: ['id_customer', 'other.id_customer'],
2045
+ used: strippedPipeline.changed
2046
+ };
2047
+ }
2048
+ pipelineWithScope = buildAssistantAggregatePipeline(scopedQuery, sanitizedPipeline);
1586
2049
  normalizedOptions = normalizeAssistantAggregateOptions(input.options);
1587
2050
  limitedPipeline = applyAssistantAggregateLimit(pipelineWithScope, normalizedOptions.limit, normalizedOptions.maxLimit, normalizedOptions.defaultLimit);
1588
2051
  dateField = findAggregateDateField(limitedPipeline);
@@ -1594,9 +2057,9 @@ function executeAiAssistantMongoAggregate(payload, context) {
1594
2057
  .aggregate(limitedPipeline, aggregateOptions)
1595
2058
  .toArray()];
1596
2059
  case 6:
1597
- documents = _e.sent();
2060
+ documents = _o.sent();
1598
2061
  executedPipeline = limitedPipeline;
1599
- fallbackMeta = {};
2062
+ probeDocs = null;
1600
2063
  if (!(!documents.length && dateField)) return [3 /*break*/, 10];
1601
2064
  fallback = resolveAggregateDateFieldFallback(limitedPipeline);
1602
2065
  if (!fallback) return [3 /*break*/, 8];
@@ -1607,13 +2070,13 @@ function executeAiAssistantMongoAggregate(payload, context) {
1607
2070
  .aggregate(fallbackPipeline, aggregateOptions)
1608
2071
  .toArray()];
1609
2072
  case 7:
1610
- fallbackDocs = _e.sent();
2073
+ fallbackDocs = _o.sent();
1611
2074
  if (fallbackDocs.length) {
1612
2075
  documents = fallbackDocs;
1613
2076
  executedPipeline = fallbackPipeline;
1614
2077
  fallbackMeta.dateField.used = true;
1615
2078
  }
1616
- _e.label = 8;
2079
+ _o.label = 8;
1617
2080
  case 8:
1618
2081
  if (!(!documents.length && dateField !== 'createdAt')) return [3 /*break*/, 10];
1619
2082
  createdFallback = { from: dateField, to: 'createdAt', attempted: true, used: false };
@@ -1624,17 +2087,38 @@ function executeAiAssistantMongoAggregate(payload, context) {
1624
2087
  .aggregate(createdPipeline, aggregateOptions)
1625
2088
  .toArray()];
1626
2089
  case 9:
1627
- createdDocs = _e.sent();
2090
+ createdDocs = _o.sent();
1628
2091
  if (createdDocs.length) {
1629
2092
  documents = createdDocs;
1630
2093
  executedPipeline = createdPipeline;
1631
2094
  fallbackMeta.dateFieldCreatedAt.used = true;
1632
2095
  }
1633
- _e.label = 10;
2096
+ _o.label = 10;
1634
2097
  case 10:
1635
- if (!!documents.length) return [3 /*break*/, 14];
2098
+ if (!!documents.length) return [3 /*break*/, 12];
2099
+ expanded = expandAggregateDateMatchFallback(executedPipeline);
2100
+ if (!expanded) return [3 /*break*/, 12];
2101
+ fallbackMeta.dateFieldsExpanded = {
2102
+ fields: expanded.fields,
2103
+ attempted: true,
2104
+ used: false
2105
+ };
2106
+ if (!!containsForbiddenMongoOperators(expanded.pipeline)) return [3 /*break*/, 12];
2107
+ return [4 /*yield*/, db.collection(collection)
2108
+ .aggregate(expanded.pipeline, aggregateOptions)
2109
+ .toArray()];
2110
+ case 11:
2111
+ expandedDocs = _o.sent();
2112
+ if (expandedDocs.length) {
2113
+ documents = expandedDocs;
2114
+ executedPipeline = expanded.pipeline;
2115
+ fallbackMeta.dateFieldsExpanded.used = true;
2116
+ }
2117
+ _o.label = 12;
2118
+ case 12:
2119
+ if (!!documents.length) return [3 /*break*/, 16];
1636
2120
  completionFallback = resolveAggregateCompletionFallback(executedPipeline);
1637
- if (!completionFallback) return [3 /*break*/, 12];
2121
+ if (!completionFallback) return [3 /*break*/, 14];
1638
2122
  fallbackMeta.completion = {
1639
2123
  field: completionFallback.field,
1640
2124
  sources: completionFallback.sources,
@@ -1644,22 +2128,22 @@ function executeAiAssistantMongoAggregate(payload, context) {
1644
2128
  strategy: 'addFields'
1645
2129
  };
1646
2130
  fallbackPipeline = buildAggregateCompletionFallbackPipeline(executedPipeline, completionFallback);
1647
- if (!(fallbackPipeline.length && !containsForbiddenMongoOperators(fallbackPipeline))) return [3 /*break*/, 12];
2131
+ if (!(fallbackPipeline.length && !containsForbiddenMongoOperators(fallbackPipeline))) return [3 /*break*/, 14];
1648
2132
  return [4 /*yield*/, db.collection(collection)
1649
2133
  .aggregate(fallbackPipeline, aggregateOptions)
1650
2134
  .toArray()];
1651
- case 11:
1652
- fallbackDocs = _e.sent();
2135
+ case 13:
2136
+ fallbackDocs = _o.sent();
1653
2137
  if (fallbackDocs.length) {
1654
2138
  documents = fallbackDocs;
1655
2139
  executedPipeline = fallbackPipeline;
1656
2140
  fallbackMeta.completion.used = true;
1657
2141
  }
1658
- _e.label = 12;
1659
- case 12:
1660
- if (!!documents.length) return [3 /*break*/, 14];
2142
+ _o.label = 14;
2143
+ case 14:
2144
+ if (!!documents.length) return [3 /*break*/, 16];
1661
2145
  completionExprFallback = resolveAggregateCompletionExprFallback(executedPipeline);
1662
- if (!completionExprFallback) return [3 /*break*/, 14];
2146
+ if (!completionExprFallback) return [3 /*break*/, 16];
1663
2147
  fallbackMeta.completion = {
1664
2148
  field: completionExprFallback.field,
1665
2149
  sources: completionExprFallback.sources,
@@ -1669,40 +2153,40 @@ function executeAiAssistantMongoAggregate(payload, context) {
1669
2153
  strategy: 'expr'
1670
2154
  };
1671
2155
  fallbackPipeline = buildAggregateCompletionExprFallbackPipeline(executedPipeline, completionExprFallback);
1672
- if (!(fallbackPipeline.length && !containsForbiddenMongoOperators(fallbackPipeline))) return [3 /*break*/, 14];
2156
+ if (!(fallbackPipeline.length && !containsForbiddenMongoOperators(fallbackPipeline))) return [3 /*break*/, 16];
1673
2157
  return [4 /*yield*/, db.collection(collection)
1674
2158
  .aggregate(fallbackPipeline, aggregateOptions)
1675
2159
  .toArray()];
1676
- case 13:
1677
- fallbackDocs = _e.sent();
2160
+ case 15:
2161
+ fallbackDocs = _o.sent();
1678
2162
  if (fallbackDocs.length) {
1679
2163
  documents = fallbackDocs;
1680
2164
  executedPipeline = fallbackPipeline;
1681
2165
  fallbackMeta.completion.used = true;
1682
2166
  }
1683
- _e.label = 14;
1684
- case 14:
1685
- if (!(documents.length <= 1)) return [3 /*break*/, 16];
2167
+ _o.label = 16;
2168
+ case 16:
2169
+ if (!(documents.length <= 1)) return [3 /*break*/, 18];
1686
2170
  unwindFallback = resolveAggregateUnwindFallback(executedPipeline);
1687
- if (!unwindFallback) return [3 /*break*/, 16];
2171
+ if (!unwindFallback) return [3 /*break*/, 18];
1688
2172
  fallbackMeta.unwind = { path: unwindFallback.path, attempted: true, used: false };
1689
2173
  fallbackPipeline = buildAggregateUnwindFallbackPipeline(executedPipeline, unwindFallback);
1690
- if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/, 16];
2174
+ if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/, 18];
1691
2175
  return [4 /*yield*/, db.collection(collection)
1692
2176
  .aggregate(fallbackPipeline, aggregateOptions)
1693
2177
  .toArray()];
1694
- case 15:
1695
- fallbackDocs = _e.sent();
2178
+ case 17:
2179
+ fallbackDocs = _o.sent();
1696
2180
  if (fallbackDocs.length > documents.length) {
1697
2181
  documents = fallbackDocs;
1698
2182
  executedPipeline = fallbackPipeline;
1699
2183
  fallbackMeta.unwind.used = true;
1700
2184
  }
1701
- _e.label = 16;
1702
- case 16:
1703
- if (!!documents.length) return [3 /*break*/, 18];
2185
+ _o.label = 18;
2186
+ case 18:
2187
+ if (!!documents.length) return [3 /*break*/, 20];
1704
2188
  nameFallback = resolveAggregateNameMatchFallback(executedPipeline);
1705
- if (!nameFallback) return [3 /*break*/, 18];
2189
+ if (!nameFallback) return [3 /*break*/, 20];
1706
2190
  fallbackMeta.nameMatch = {
1707
2191
  field: nameFallback.field,
1708
2192
  fields: nameFallback.fields,
@@ -1710,24 +2194,346 @@ function executeAiAssistantMongoAggregate(payload, context) {
1710
2194
  used: false
1711
2195
  };
1712
2196
  fallbackPipeline = buildAggregateNameMatchFallbackPipeline(executedPipeline, nameFallback);
1713
- if (!(fallbackPipeline.length && !containsForbiddenMongoOperators(fallbackPipeline))) return [3 /*break*/, 18];
2197
+ if (!(fallbackPipeline.length && !containsForbiddenMongoOperators(fallbackPipeline))) return [3 /*break*/, 20];
1714
2198
  return [4 /*yield*/, db.collection(collection)
1715
2199
  .aggregate(fallbackPipeline, aggregateOptions)
1716
2200
  .toArray()];
1717
- case 17:
1718
- fallbackDocs = _e.sent();
2201
+ case 19:
2202
+ fallbackDocs = _o.sent();
1719
2203
  if (fallbackDocs.length) {
1720
2204
  documents = fallbackDocs;
1721
2205
  executedPipeline = fallbackPipeline;
1722
2206
  fallbackMeta.nameMatch.used = true;
1723
2207
  }
1724
- _e.label = 18;
1725
- case 18:
2208
+ _o.label = 20;
2209
+ case 20:
2210
+ if (!!documents.length) return [3 /*break*/, 26];
2211
+ _c = probeDocs;
2212
+ if (_c) return [3 /*break*/, 22];
2213
+ return [4 /*yield*/, fetchAssistantProbeDocs({
2214
+ db: db,
2215
+ collection: collection,
2216
+ idClient: normalizedClient,
2217
+ idCustomer: customerId,
2218
+ isSuperAdmin: isSuperAdmin,
2219
+ includeClientScope: shouldScopeByClient
2220
+ })];
2221
+ case 21:
2222
+ _c = (_o.sent());
2223
+ _o.label = 22;
2224
+ case 22:
2225
+ probeDocs = _c;
2226
+ _loop_1 = function (i) {
2227
+ var stage, chemicalLookup, rewrittenPipeline, fallbackDocs;
2228
+ return __generator(this, function (_p) {
2229
+ switch (_p.label) {
2230
+ case 0:
2231
+ stage = executedPipeline[i];
2232
+ if (!stage || typeof stage !== 'object' || !stage.$match || typeof stage.$match !== 'object') {
2233
+ return [2 /*return*/, "continue"];
2234
+ }
2235
+ return [4 /*yield*/, applyChemicalNameLookupFallbackToQuery({
2236
+ query: stage.$match,
2237
+ db: db,
2238
+ dbName: dbName,
2239
+ idClient: normalizedClient,
2240
+ idCustomer: customerId,
2241
+ isSuperAdmin: isSuperAdmin,
2242
+ probeDocs: probeDocs || undefined
2243
+ })];
2244
+ case 1:
2245
+ chemicalLookup = _p.sent();
2246
+ if (!chemicalLookup) {
2247
+ return [2 /*return*/, "continue"];
2248
+ }
2249
+ fallbackMeta.chemicalLookup = __assign(__assign({}, chemicalLookup.meta), { attempted: true, used: false, stage: i });
2250
+ rewrittenPipeline = executedPipeline.map(function (current, index) { return (index === i ? { $match: chemicalLookup.query } : current); });
2251
+ if (!!containsForbiddenMongoOperators(rewrittenPipeline)) return [3 /*break*/, 3];
2252
+ return [4 /*yield*/, db.collection(collection)
2253
+ .aggregate(rewrittenPipeline, aggregateOptions)
2254
+ .toArray()];
2255
+ case 2:
2256
+ fallbackDocs = _p.sent();
2257
+ if (fallbackDocs.length) {
2258
+ documents = fallbackDocs;
2259
+ executedPipeline = rewrittenPipeline;
2260
+ fallbackMeta.chemicalLookup.used = true;
2261
+ return [2 /*return*/, "break"];
2262
+ }
2263
+ _p.label = 3;
2264
+ case 3: return [2 /*return*/];
2265
+ }
2266
+ });
2267
+ };
2268
+ i = 0;
2269
+ _o.label = 23;
2270
+ case 23:
2271
+ if (!(i < (executedPipeline || []).length)) return [3 /*break*/, 26];
2272
+ return [5 /*yield**/, _loop_1(i)];
2273
+ case 24:
2274
+ state_1 = _o.sent();
2275
+ if (state_1 === "break")
2276
+ return [3 /*break*/, 26];
2277
+ _o.label = 25;
2278
+ case 25:
2279
+ i += 1;
2280
+ return [3 /*break*/, 23];
2281
+ case 26:
2282
+ if (!!documents.length) return [3 /*break*/, 30];
2283
+ matchFields_1 = new Set();
2284
+ (executedPipeline || []).forEach(function (stage) {
2285
+ if (stage && typeof stage === 'object' && stage.$match && typeof stage.$match === 'object') {
2286
+ extractQueryFieldPaths(stage.$match)
2287
+ .filter(function (field) { return !isAssistantIdField(field); })
2288
+ .forEach(function (field) { return matchFields_1.add(field); });
2289
+ }
2290
+ });
2291
+ if (!matchFields_1.size) return [3 /*break*/, 30];
2292
+ _d = probeDocs;
2293
+ if (_d) return [3 /*break*/, 28];
2294
+ return [4 /*yield*/, fetchAssistantProbeDocs({
2295
+ db: db,
2296
+ collection: collection,
2297
+ idClient: normalizedClient,
2298
+ idCustomer: customerId,
2299
+ isSuperAdmin: isSuperAdmin,
2300
+ includeClientScope: shouldScopeByClient
2301
+ })];
2302
+ case 27:
2303
+ _d = (_o.sent());
2304
+ _o.label = 28;
2305
+ case 28:
2306
+ probeDocs = _d;
2307
+ if (!probeDocs.length) return [3 /*break*/, 30];
2308
+ aliases = resolveFieldAliases(probeDocs, Array.from(matchFields_1), schemaFields);
2309
+ if (!Object.keys(aliases).length) return [3 /*break*/, 30];
2310
+ fallbackMeta.queryFieldAliases = {
2311
+ aliases: aliases,
2312
+ attempted: true,
2313
+ used: false
2314
+ };
2315
+ rewrittenPipeline = Object.entries(aliases)
2316
+ .reduce(function (acc, _a) {
2317
+ var _b = __read(_a, 2), from = _b[0], to = _b[1];
2318
+ return replaceFieldPathDeep(acc, from, to);
2319
+ }, executedPipeline);
2320
+ if (!!containsForbiddenMongoOperators(rewrittenPipeline)) return [3 /*break*/, 30];
2321
+ return [4 /*yield*/, db.collection(collection)
2322
+ .aggregate(rewrittenPipeline, aggregateOptions)
2323
+ .toArray()];
2324
+ case 29:
2325
+ fallbackDocs = _o.sent();
2326
+ if (fallbackDocs.length) {
2327
+ documents = fallbackDocs;
2328
+ executedPipeline = rewrittenPipeline;
2329
+ fallbackMeta.queryFieldAliases.used = true;
2330
+ }
2331
+ _o.label = 30;
2332
+ case 30:
2333
+ if (!!documents.length) return [3 /*break*/, 34];
2334
+ _loop_2 = function (i) {
2335
+ var stage, _q, idLookup, rewrittenPipeline, fallbackDocs;
2336
+ return __generator(this, function (_r) {
2337
+ switch (_r.label) {
2338
+ case 0:
2339
+ stage = executedPipeline[i];
2340
+ if (!stage || typeof stage !== 'object' || !stage.$match || typeof stage.$match !== 'object') {
2341
+ return [2 /*return*/, "continue"];
2342
+ }
2343
+ _q = probeDocs;
2344
+ if (_q) return [3 /*break*/, 2];
2345
+ return [4 /*yield*/, fetchAssistantProbeDocs({
2346
+ db: db,
2347
+ collection: collection,
2348
+ idClient: normalizedClient,
2349
+ idCustomer: customerId,
2350
+ isSuperAdmin: isSuperAdmin,
2351
+ includeClientScope: shouldScopeByClient
2352
+ })];
2353
+ case 1:
2354
+ _q = (_r.sent());
2355
+ _r.label = 2;
2356
+ case 2:
2357
+ probeDocs = _q;
2358
+ return [4 /*yield*/, applyIdLookupFallbackToQuery({
2359
+ query: stage.$match,
2360
+ db: db,
2361
+ dbName: dbName,
2362
+ idClient: normalizedClient,
2363
+ idCustomer: customerId,
2364
+ isSuperAdmin: isSuperAdmin,
2365
+ probeDocs: probeDocs || undefined
2366
+ })];
2367
+ case 3:
2368
+ idLookup = _r.sent();
2369
+ if (!idLookup) {
2370
+ return [2 /*return*/, "continue"];
2371
+ }
2372
+ fallbackMeta.idLookup = __assign(__assign({}, idLookup.meta), { attempted: true, used: false, stage: i });
2373
+ rewrittenPipeline = executedPipeline.map(function (current, index) { return (index === i ? { $match: idLookup.query } : current); });
2374
+ if (!!containsForbiddenMongoOperators(rewrittenPipeline)) return [3 /*break*/, 5];
2375
+ return [4 /*yield*/, db.collection(collection)
2376
+ .aggregate(rewrittenPipeline, aggregateOptions)
2377
+ .toArray()];
2378
+ case 4:
2379
+ fallbackDocs = _r.sent();
2380
+ if (fallbackDocs.length) {
2381
+ documents = fallbackDocs;
2382
+ executedPipeline = rewrittenPipeline;
2383
+ fallbackMeta.idLookup.used = true;
2384
+ return [2 /*return*/, "break"];
2385
+ }
2386
+ _r.label = 5;
2387
+ case 5: return [2 /*return*/];
2388
+ }
2389
+ });
2390
+ };
2391
+ i = 0;
2392
+ _o.label = 31;
2393
+ case 31:
2394
+ if (!(i < (executedPipeline || []).length)) return [3 /*break*/, 34];
2395
+ return [5 /*yield**/, _loop_2(i)];
2396
+ case 32:
2397
+ state_2 = _o.sent();
2398
+ if (state_2 === "break")
2399
+ return [3 /*break*/, 34];
2400
+ _o.label = 33;
2401
+ case 33:
2402
+ i += 1;
2403
+ return [3 /*break*/, 31];
2404
+ case 34:
2405
+ if (!!documents.length) return [3 /*break*/, 37];
2406
+ return [4 /*yield*/, resolveBaseCollectionFromReport(db, dbName, collection)];
2407
+ case 35:
2408
+ baseCollection = _o.sent();
2409
+ if (!(baseCollection && baseCollection !== collection)) return [3 /*break*/, 37];
2410
+ fallbackPayload = __assign(__assign({}, input), { collection: baseCollection });
2411
+ return [4 /*yield*/, executeAiAssistantMongoAggregate(fallbackPayload, context)];
2412
+ case 36:
2413
+ fallbackResult = _o.sent();
2414
+ if (Array.isArray(fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.documents) && fallbackResult.documents.length) {
2415
+ if (isSuperAdmin && (fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.debug) && typeof fallbackResult.debug === 'object') {
2416
+ existingFallbacks = fallbackResult.debug.fallbacks && typeof fallbackResult.debug.fallbacks === 'object'
2417
+ ? fallbackResult.debug.fallbacks
2418
+ : {};
2419
+ fallbackResult.debug.fallbacks = __assign(__assign({}, existingFallbacks), { reportFallback: {
2420
+ from: collection,
2421
+ to: baseCollection,
2422
+ used: true
2423
+ } });
2424
+ }
2425
+ return [2 /*return*/, fallbackResult];
2426
+ }
2427
+ if (isSuperAdmin) {
2428
+ fallbackMeta.reportFallback = { from: collection, to: baseCollection, attempted: true, used: false };
2429
+ }
2430
+ _o.label = 37;
2431
+ case 37:
2432
+ if (!(!documents.length && isSuperAdmin)) return [3 /*break*/, 54];
2433
+ matchStages = (executedPipeline || []).filter(function (stage) { return stage && typeof stage === 'object' && stage.$match && typeof stage.$match === 'object'; });
2434
+ diagnostics = {};
2435
+ if (!matchStages.length) return [3 /*break*/, 54];
2436
+ combinedMatch = matchStages.reduce(function (acc, stage) { return ({ $and: __spreadArray(__spreadArray([], __read((acc.$and || [])), false), [stage.$match], false) }); }, { $and: [] });
2437
+ nameFields = collectMatchFieldsByCondition(combinedMatch, function (field, condition) { return isRegexMatchCondition(condition)
2438
+ || (typeof condition === 'string' && shouldApplyAssistantNameRegex(field)); });
2439
+ dateFields = collectMatchFieldsByCondition(combinedMatch, function (_field, condition) { return isDateCondition(condition); });
2440
+ diagnostics.nameFields = nameFields.length ? nameFields : undefined;
2441
+ diagnostics.dateFields = dateFields.length ? dateFields : undefined;
2442
+ _o.label = 38;
2443
+ case 38:
2444
+ _o.trys.push([38, 43, , 44]);
2445
+ if (!nameFields.length) return [3 /*break*/, 40];
2446
+ queryNoName = stripMatchFields(combinedMatch, nameFields);
2447
+ _e = diagnostics;
2448
+ return [4 /*yield*/, db.collection(collection).countDocuments(queryNoName, {
2449
+ readPreference: AI_ASSISTANT_READ_PREFERENCE
2450
+ })];
2451
+ case 39:
2452
+ _e.recentCount = _o.sent();
2453
+ _o.label = 40;
2454
+ case 40:
2455
+ if (!dateFields.length) return [3 /*break*/, 42];
2456
+ queryNoDate = stripMatchFields(combinedMatch, dateFields);
2457
+ _f = diagnostics;
2458
+ return [4 /*yield*/, db.collection(collection).countDocuments(queryNoDate, {
2459
+ readPreference: AI_ASSISTANT_READ_PREFERENCE
2460
+ })];
2461
+ case 41:
2462
+ _f.nameMatchCount = _o.sent();
2463
+ _o.label = 42;
2464
+ case 42: return [3 /*break*/, 44];
2465
+ case 43:
2466
+ _g = _o.sent();
2467
+ return [3 /*break*/, 44];
2468
+ case 44:
2469
+ _o.trys.push([44, 47, , 48]);
2470
+ _h = probeDocs;
2471
+ if (_h) return [3 /*break*/, 46];
2472
+ return [4 /*yield*/, fetchAssistantProbeDocs({
2473
+ db: db,
2474
+ collection: collection,
2475
+ idClient: normalizedClient,
2476
+ idCustomer: customerId,
2477
+ isSuperAdmin: isSuperAdmin,
2478
+ includeClientScope: shouldScopeByClient
2479
+ })];
2480
+ case 45:
2481
+ _h = (_o.sent());
2482
+ _o.label = 46;
2483
+ case 46:
2484
+ probeDocs = _h;
2485
+ if (probeDocs.length && nameFields.length) {
2486
+ diagnostics.chemicalIdDetected = detectChemicalIdFromProbe(probeDocs, nameFields);
2487
+ }
2488
+ return [3 /*break*/, 48];
2489
+ case 47:
2490
+ _j = _o.sent();
2491
+ return [3 /*break*/, 48];
2492
+ case 48:
2493
+ _o.trys.push([48, 52, , 53]);
2494
+ return [4 /*yield*/, listAssistantCollections(db, dbName)];
2495
+ case 49:
2496
+ allCollections = _o.sent();
2497
+ base = stripVersionSuffix(collection.startsWith('report-') ? collection.slice('report-'.length) : collection);
2498
+ alt = collection.startsWith('report-') ? base : "report-".concat(base);
2499
+ if (!(alt && alt !== collection && allCollections.includes(alt))) return [3 /*break*/, 51];
2500
+ return [4 /*yield*/, db.collection(alt).countDocuments({}, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
2501
+ case 50:
2502
+ altCount = _o.sent();
2503
+ diagnostics.alternateCollection = alt;
2504
+ diagnostics.alternateCollectionCount = altCount;
2505
+ _o.label = 51;
2506
+ case 51: return [3 /*break*/, 53];
2507
+ case 52:
2508
+ _k = _o.sent();
2509
+ return [3 /*break*/, 53];
2510
+ case 53:
2511
+ fallbackMeta.zeroDiagnostics = diagnostics;
2512
+ _o.label = 54;
2513
+ case 54:
1726
2514
  sanitizedDocuments = isSuperAdmin
1727
2515
  ? documents
1728
2516
  : documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
1729
- includeIds = ((_d = input.options) === null || _d === void 0 ? void 0 : _d.includeIds) === true;
1730
- display = buildDisplayTable(sanitizedDocuments, {
2517
+ includeIds = ((_m = input.options) === null || _m === void 0 ? void 0 : _m.includeIds) === true;
2518
+ displayDocs = sanitizedDocuments;
2519
+ return [4 /*yield*/, applyIdLookupDisplayEnrichment({
2520
+ docs: displayDocs,
2521
+ collection: collection,
2522
+ db: db,
2523
+ dbName: dbName,
2524
+ idClient: normalizedClient,
2525
+ idCustomer: customerId,
2526
+ isSuperAdmin: isSuperAdmin
2527
+ })];
2528
+ case 55:
2529
+ idLookupDisplay = _o.sent();
2530
+ if (idLookupDisplay === null || idLookupDisplay === void 0 ? void 0 : idLookupDisplay.docs) {
2531
+ displayDocs = idLookupDisplay.docs;
2532
+ }
2533
+ if (idLookupDisplay === null || idLookupDisplay === void 0 ? void 0 : idLookupDisplay.meta) {
2534
+ fallbackMeta.idDisplayLookup = idLookupDisplay.meta;
2535
+ }
2536
+ display = buildDisplayTable(displayDocs, {
1731
2537
  includeIds: includeIds,
1732
2538
  maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
1733
2539
  maxRows: normalizedOptions.limit || sanitizedDocuments.length,
@@ -1901,7 +2707,7 @@ function buildAssistantToolFallbackResponse(result) {
1901
2707
  return lines.join('\n').trim();
1902
2708
  }
1903
2709
  function buildAssistantDebugPayload(params) {
1904
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
2710
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
1905
2711
  var notes = [];
1906
2712
  if (params.dataQuestion) {
1907
2713
  notes.push('Detected a data request; tool call required.');
@@ -1909,18 +2715,24 @@ function buildAssistantDebugPayload(params) {
1909
2715
  if (params.directiveSource === 'forced') {
1910
2716
  notes.push('Assistant response omitted a MONGO_* directive; ran a directive-only pass.');
1911
2717
  }
2718
+ if ((_a = params.collectionOverride) === null || _a === void 0 ? void 0 : _a.to) {
2719
+ var from = params.collectionOverride.from ? "\"".concat(params.collectionOverride.from, "\"") : '(none)';
2720
+ var to = "\"".concat(params.collectionOverride.to, "\"");
2721
+ var reason = params.collectionOverride.reason ? " (".concat(params.collectionOverride.reason, ")") : '';
2722
+ notes.push("Collection override: ".concat(from, " -> ").concat(to).concat(reason, "."));
2723
+ }
1912
2724
  var directive = params.directive;
1913
2725
  var directivePayload = (directive === null || directive === void 0 ? void 0 : directive.payload) || {};
1914
2726
  var rawCollection = normalizeOptionalString(directivePayload === null || directivePayload === void 0 ? void 0 : directivePayload.collection);
1915
- var debugCollectionRequested = normalizeOptionalString((_a = params.toolResponseDebug) === null || _a === void 0 ? void 0 : _a.collectionRequested);
1916
- var debugCollectionResolved = normalizeOptionalString((_b = params.toolResponseDebug) === null || _b === void 0 ? void 0 : _b.collectionResolved);
1917
- var debugCollection = normalizeOptionalString((_c = params.toolResponseDebug) === null || _c === void 0 ? void 0 : _c.collection);
2727
+ var debugCollectionRequested = normalizeOptionalString((_b = params.toolResponseDebug) === null || _b === void 0 ? void 0 : _b.collectionRequested);
2728
+ var debugCollectionResolved = normalizeOptionalString((_c = params.toolResponseDebug) === null || _c === void 0 ? void 0 : _c.collectionResolved);
2729
+ var debugCollection = normalizeOptionalString((_d = params.toolResponseDebug) === null || _d === void 0 ? void 0 : _d.collection);
1918
2730
  var requestedCollection = debugCollectionRequested || rawCollection;
1919
2731
  var resolvedCollection = debugCollectionResolved || debugCollection || requestedCollection;
1920
- var matchedCollection = typeof ((_d = params.toolResponseDebug) === null || _d === void 0 ? void 0 : _d.collectionMatched) === 'boolean'
2732
+ var matchedCollection = typeof ((_e = params.toolResponseDebug) === null || _e === void 0 ? void 0 : _e.collectionMatched) === 'boolean'
1921
2733
  ? params.toolResponseDebug.collectionMatched
1922
2734
  : undefined;
1923
- var candidateCollections = Array.isArray((_e = params.toolResponseDebug) === null || _e === void 0 ? void 0 : _e.collectionCandidates)
2735
+ var candidateCollections = Array.isArray((_f = params.toolResponseDebug) === null || _f === void 0 ? void 0 : _f.collectionCandidates)
1924
2736
  ? params.toolResponseDebug.collectionCandidates.filter(Boolean)
1925
2737
  : [];
1926
2738
  if (requestedCollection && resolvedCollection && requestedCollection !== resolvedCollection) {
@@ -1929,27 +2741,27 @@ function buildAssistantDebugPayload(params) {
1929
2741
  else if (matchedCollection === false && candidateCollections.length) {
1930
2742
  notes.push("No direct collection match; candidates: ".concat(candidateCollections.join(', '), "."));
1931
2743
  }
1932
- if (((_f = params.toolResult) === null || _f === void 0 ? void 0 : _f.type) === 'mongo_agg') {
2744
+ if (((_g = params.toolResult) === null || _g === void 0 ? void 0 : _g.type) === 'mongo_agg') {
1933
2745
  notes.push('Used aggregation for grouped/breakdown request.');
1934
2746
  }
1935
- else if (((_g = params.toolResult) === null || _g === void 0 ? void 0 : _g.type) === 'mongo_read') {
2747
+ else if (((_h = params.toolResult) === null || _h === void 0 ? void 0 : _h.type) === 'mongo_read') {
1936
2748
  notes.push('Used read query for list/count request.');
1937
2749
  }
1938
- var fallbackInfo = (_h = params.toolResponseDebug) === null || _h === void 0 ? void 0 : _h.fallbacks;
1939
- if ((_j = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateField) === null || _j === void 0 ? void 0 : _j.used) {
2750
+ var fallbackInfo = (_j = params.toolResponseDebug) === null || _j === void 0 ? void 0 : _j.fallbacks;
2751
+ if ((_k = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateField) === null || _k === void 0 ? void 0 : _k.used) {
1940
2752
  notes.push("Retried with date field fallback ".concat(fallbackInfo.dateField.from, " -> ").concat(fallbackInfo.dateField.to, "."));
1941
2753
  }
1942
- if ((_k = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateFieldCreatedAt) === null || _k === void 0 ? void 0 : _k.used) {
2754
+ if ((_l = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateFieldCreatedAt) === null || _l === void 0 ? void 0 : _l.used) {
1943
2755
  notes.push("Retried with date field fallback ".concat(fallbackInfo.dateFieldCreatedAt.from, " -> ").concat(fallbackInfo.dateFieldCreatedAt.to, "."));
1944
2756
  }
1945
- if ((_l = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.completion) === null || _l === void 0 ? void 0 : _l.used) {
2757
+ if ((_m = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.completion) === null || _m === void 0 ? void 0 : _m.used) {
1946
2758
  var sources = Array.isArray(fallbackInfo.completion.sources)
1947
2759
  ? fallbackInfo.completion.sources.join(', ')
1948
2760
  : fallbackInfo.completion.field;
1949
2761
  var strategy = fallbackInfo.completion.strategy ? " (".concat(fallbackInfo.completion.strategy, ")") : '';
1950
2762
  notes.push("Applied completion fallback".concat(strategy, ": ").concat(sources, "."));
1951
2763
  }
1952
- if ((_m = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateFieldsExpanded) === null || _m === void 0 ? void 0 : _m.used) {
2764
+ if ((_o = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateFieldsExpanded) === null || _o === void 0 ? void 0 : _o.used) {
1953
2765
  var fields = Array.isArray(fallbackInfo.dateFieldsExpanded.fields)
1954
2766
  ? fallbackInfo.dateFieldsExpanded.fields.join(', ')
1955
2767
  : String(fallbackInfo.dateFieldsExpanded.fields || '');
@@ -1957,17 +2769,69 @@ function buildAssistantDebugPayload(params) {
1957
2769
  notes.push("Expanded date fields: ".concat(fields, "."));
1958
2770
  }
1959
2771
  }
1960
- if ((_o = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.unwind) === null || _o === void 0 ? void 0 : _o.used) {
2772
+ if ((_p = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.queryFieldAliases) === null || _p === void 0 ? void 0 : _p.used) {
2773
+ var entries = fallbackInfo.queryFieldAliases.aliases
2774
+ ? Object.entries(fallbackInfo.queryFieldAliases.aliases)
2775
+ .map(function (_a) {
2776
+ var _b = __read(_a, 2), from = _b[0], to = _b[1];
2777
+ return "".concat(from, " -> ").concat(to);
2778
+ })
2779
+ .join(', ')
2780
+ : '';
2781
+ if (entries) {
2782
+ notes.push("Rewrote query fields: ".concat(entries, "."));
2783
+ }
2784
+ }
2785
+ if ((_q = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.projectionAliases) === null || _q === void 0 ? void 0 : _q.used) {
2786
+ var entries = fallbackInfo.projectionAliases.aliases
2787
+ ? Object.entries(fallbackInfo.projectionAliases.aliases)
2788
+ .map(function (_a) {
2789
+ var _b = __read(_a, 2), from = _b[0], to = _b[1];
2790
+ return "".concat(from, " -> ").concat(to);
2791
+ })
2792
+ .join(', ')
2793
+ : '';
2794
+ if (entries) {
2795
+ notes.push("Expanded projection fields: ".concat(entries, "."));
2796
+ }
2797
+ }
2798
+ if ((_r = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.unwind) === null || _r === void 0 ? void 0 : _r.used) {
1961
2799
  notes.push("Applied unwind fallback on ".concat(fallbackInfo.unwind.path, "."));
1962
2800
  }
1963
- if ((_p = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.nameMatch) === null || _p === void 0 ? void 0 : _p.used) {
2801
+ if ((_s = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.nameMatch) === null || _s === void 0 ? void 0 : _s.used) {
1964
2802
  var fields = Array.isArray(fallbackInfo.nameMatch.fields)
1965
2803
  ? fallbackInfo.nameMatch.fields.join(', ')
1966
2804
  : fallbackInfo.nameMatch.field;
1967
2805
  notes.push("Expanded name match fields: ".concat(fields, "."));
1968
2806
  }
2807
+ if ((_t = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.chemicalLookup) === null || _t === void 0 ? void 0 : _t.used) {
2808
+ var collection = fallbackInfo.chemicalLookup.collection ? " in ".concat(fallbackInfo.chemicalLookup.collection) : '';
2809
+ notes.push("Applied chemical lookup".concat(collection, "."));
2810
+ }
2811
+ if ((_u = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.reportFallback) === null || _u === void 0 ? void 0 : _u.used) {
2812
+ var from = fallbackInfo.reportFallback.from || 'report';
2813
+ var to = fallbackInfo.reportFallback.to || 'base';
2814
+ notes.push("Report fallback: ".concat(from, " -> ").concat(to, "."));
2815
+ }
2816
+ if ((_v = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.idLookup) === null || _v === void 0 ? void 0 : _v.used) {
2817
+ var field = fallbackInfo.idLookup.field || 'id';
2818
+ var strategy = fallbackInfo.idLookup.strategy || 'lookup';
2819
+ var collection = fallbackInfo.idLookup.collection ? " in ".concat(fallbackInfo.idLookup.collection) : '';
2820
+ var detail = fallbackInfo.idLookup.nameField ? " via ".concat(fallbackInfo.idLookup.nameField) : '';
2821
+ notes.push("Resolved ".concat(field, " by ").concat(strategy).concat(collection).concat(detail, "."));
2822
+ }
2823
+ if ((_w = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.idDisplayLookup) === null || _w === void 0 ? void 0 : _w.used) {
2824
+ var lookups = Array.isArray(fallbackInfo.idDisplayLookup.lookups)
2825
+ ? fallbackInfo.idDisplayLookup.lookups
2826
+ : [];
2827
+ var summary = lookups
2828
+ .map(function (entry) { return (entry === null || entry === void 0 ? void 0 : entry.displayField) || (entry === null || entry === void 0 ? void 0 : entry.field); })
2829
+ .filter(Boolean)
2830
+ .join(', ');
2831
+ notes.push(summary ? "Resolved id lookups for display: ".concat(summary, ".") : 'Resolved id lookups for display.');
2832
+ }
1969
2833
  if (params.toolError) {
1970
- var errorMessage = ((_q = params.toolError) === null || _q === void 0 ? void 0 : _q.message) || String(params.toolError || '');
2834
+ var errorMessage = ((_x = params.toolError) === null || _x === void 0 ? void 0 : _x.message) || String(params.toolError || '');
1971
2835
  if (errorMessage) {
1972
2836
  notes.push("Tool error: ".concat(errorMessage));
1973
2837
  }
@@ -1982,18 +2846,19 @@ function buildAssistantDebugPayload(params) {
1982
2846
  payload: directivePayload,
1983
2847
  rawLine: directive.rawLine
1984
2848
  } : null,
2849
+ collectionOverride: params.collectionOverride || undefined,
1985
2850
  collection: resolvedCollection || requestedCollection || undefined,
1986
2851
  collectionRequested: requestedCollection || undefined,
1987
2852
  collectionResolved: resolvedCollection || undefined,
1988
2853
  collectionMatched: matchedCollection,
1989
2854
  collectionCandidates: candidateCollections.length ? candidateCollections : undefined,
1990
- collectionScore: typeof ((_r = params.toolResponseDebug) === null || _r === void 0 ? void 0 : _r.collectionScore) === 'number'
2855
+ collectionScore: typeof ((_y = params.toolResponseDebug) === null || _y === void 0 ? void 0 : _y.collectionScore) === 'number'
1991
2856
  ? params.toolResponseDebug.collectionScore
1992
2857
  : undefined,
1993
- query: ((_s = params.toolResponseDebug) === null || _s === void 0 ? void 0 : _s.query) || undefined,
1994
- pipeline: ((_t = params.toolResponseDebug) === null || _t === void 0 ? void 0 : _t.executedPipeline) || ((_u = params.toolResponseDebug) === null || _u === void 0 ? void 0 : _u.originalPipeline) || undefined,
1995
- options: ((_v = params.toolResponseDebug) === null || _v === void 0 ? void 0 : _v.options) || undefined,
1996
- fallbacks: ((_w = params.toolResponseDebug) === null || _w === void 0 ? void 0 : _w.fallbacks) || undefined,
2858
+ query: ((_z = params.toolResponseDebug) === null || _z === void 0 ? void 0 : _z.query) || undefined,
2859
+ pipeline: ((_0 = params.toolResponseDebug) === null || _0 === void 0 ? void 0 : _0.executedPipeline) || ((_1 = params.toolResponseDebug) === null || _1 === void 0 ? void 0 : _1.originalPipeline) || undefined,
2860
+ options: ((_2 = params.toolResponseDebug) === null || _2 === void 0 ? void 0 : _2.options) || undefined,
2861
+ fallbacks: ((_3 = params.toolResponseDebug) === null || _3 === void 0 ? void 0 : _3.fallbacks) || undefined,
1997
2862
  notes: notes
1998
2863
  };
1999
2864
  if (params.trace && typeof params.trace === 'object') {
@@ -2260,76 +3125,698 @@ function tokenizeFieldKey(value) {
2260
3125
  function normalizeFieldMatchKey(value) {
2261
3126
  return tokenizeFieldKey(value).join('');
2262
3127
  }
3128
+ function getCollectionSchemaFieldNames(collectionName) {
3129
+ var _a;
3130
+ var normalized = normalizeOptionalString(collectionName);
3131
+ if (!normalized) {
3132
+ return [];
3133
+ }
3134
+ try {
3135
+ var collection = (_a = resolveio_server_app_1.ResolveIOServer.getMongoManager()) === null || _a === void 0 ? void 0 : _a.collection(normalized);
3136
+ var schema = collection === null || collection === void 0 ? void 0 : collection.simplschema;
3137
+ var fields_1 = schema && typeof schema.schema === 'function'
3138
+ ? Object.keys(schema.schema())
3139
+ : [];
3140
+ var rbSchema = collection === null || collection === void 0 ? void 0 : collection.rbSchema;
3141
+ if (rbSchema && typeof rbSchema === 'object') {
3142
+ Object.keys(rbSchema).forEach(function (field) {
3143
+ if (field && !fields_1.includes(field)) {
3144
+ fields_1.push(field);
3145
+ }
3146
+ });
3147
+ }
3148
+ return fields_1;
3149
+ }
3150
+ catch (_b) {
3151
+ return [];
3152
+ }
3153
+ }
3154
+ function getCollectionLookupMappings(collectionName) {
3155
+ var _a;
3156
+ var normalized = normalizeOptionalString(collectionName);
3157
+ if (!normalized) {
3158
+ return [];
3159
+ }
3160
+ try {
3161
+ var collection = (_a = resolveio_server_app_1.ResolveIOServer.getMongoManager()) === null || _a === void 0 ? void 0 : _a.collection(normalized);
3162
+ var rbSchema_1 = collection === null || collection === void 0 ? void 0 : collection.rbSchema;
3163
+ if (!rbSchema_1 || typeof rbSchema_1 !== 'object') {
3164
+ return [];
3165
+ }
3166
+ var mappings_1 = [];
3167
+ Object.keys(rbSchema_1).forEach(function (key) {
3168
+ var entry = rbSchema_1[key];
3169
+ if (!entry || typeof entry !== 'object') {
3170
+ return;
3171
+ }
3172
+ var lookupCollection = normalizeOptionalString(entry.lookup_collection);
3173
+ var localKey = normalizeOptionalString(entry.local_key);
3174
+ if (!lookupCollection || !localKey) {
3175
+ return;
3176
+ }
3177
+ var lookupKey = normalizeOptionalString(entry.lookup_key) || '_id';
3178
+ mappings_1.push({ localKey: localKey, lookupCollection: lookupCollection, lookupKey: lookupKey });
3179
+ });
3180
+ return mappings_1;
3181
+ }
3182
+ catch (_b) {
3183
+ return [];
3184
+ }
3185
+ }
3186
+ function normalizeLookupPath(value) {
3187
+ var trimmed = normalizeOptionalString(value);
3188
+ if (!trimmed) {
3189
+ return '';
3190
+ }
3191
+ return trimmed
3192
+ .replace(/\.\$\./g, '.')
3193
+ .replace(/\.\$/g, '.')
3194
+ .replace(/\.\d+\./g, '.')
3195
+ .replace(/\.\d+$/g, '')
3196
+ .replace(/\.+/g, '.')
3197
+ .replace(/^\./, '')
3198
+ .replace(/\.$/, '');
3199
+ }
3200
+ function isUnsafeFieldAlias(requestedTokens, candidateTokens) {
3201
+ var reqSet = new Set(requestedTokens);
3202
+ var candSet = new Set(candidateTokens);
3203
+ var hasReqCreated = reqSet.has('created') || reqSet.has('create');
3204
+ var hasReqUpdated = reqSet.has('updated') || reqSet.has('update') || reqSet.has('modified') || reqSet.has('modify');
3205
+ var hasCandCreated = candSet.has('created') || candSet.has('create');
3206
+ var hasCandUpdated = candSet.has('updated') || candSet.has('update') || candSet.has('modified') || candSet.has('modify');
3207
+ if (hasReqCreated && hasCandUpdated && !hasCandCreated) {
3208
+ return true;
3209
+ }
3210
+ if (hasReqUpdated && hasCandCreated && !hasCandUpdated) {
3211
+ return true;
3212
+ }
3213
+ return false;
3214
+ }
3215
+ function expandFieldTokens(tokens) {
3216
+ var expanded = new Set();
3217
+ tokens.forEach(function (token) {
3218
+ if (!token) {
3219
+ return;
3220
+ }
3221
+ expanded.add(token);
3222
+ var synonyms = AI_ASSISTANT_FIELD_TOKEN_SYNONYMS[token];
3223
+ if (Array.isArray(synonyms)) {
3224
+ synonyms.forEach(function (synonym) {
3225
+ if (synonym) {
3226
+ expanded.add(synonym);
3227
+ }
3228
+ });
3229
+ }
3230
+ });
3231
+ return Array.from(expanded);
3232
+ }
2263
3233
  function getValueAtPath(obj, path) {
2264
- var e_1, _a;
2265
3234
  if (!obj || typeof obj !== 'object') {
2266
3235
  return undefined;
2267
3236
  }
2268
3237
  var parts = String(path || '').split('.').filter(Boolean);
2269
- var current = obj;
2270
- try {
2271
- for (var parts_1 = __values(parts), parts_1_1 = parts_1.next(); !parts_1_1.done; parts_1_1 = parts_1.next()) {
2272
- var part = parts_1_1.value;
2273
- if (!current || typeof current !== 'object') {
3238
+ var walk = function (current, index) {
3239
+ if (index >= parts.length) {
3240
+ return current;
3241
+ }
3242
+ var part = parts[index];
3243
+ if (Array.isArray(current)) {
3244
+ var numeric = Number(part);
3245
+ if (!Number.isNaN(numeric) && current[numeric] !== undefined) {
3246
+ return walk(current[numeric], index + 1);
3247
+ }
3248
+ var values = current.map(function (entry) { return walk(entry, index); }).filter(function (value) { return value !== undefined; });
3249
+ if (!values.length) {
2274
3250
  return undefined;
2275
3251
  }
2276
- current = current[part];
3252
+ return values.length === 1 ? values[0] : values;
2277
3253
  }
2278
- }
2279
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2280
- finally {
2281
- try {
2282
- if (parts_1_1 && !parts_1_1.done && (_a = parts_1.return)) _a.call(parts_1);
3254
+ if (!current || typeof current !== 'object') {
3255
+ return undefined;
2283
3256
  }
2284
- finally { if (e_1) throw e_1.error; }
2285
- }
2286
- return current;
3257
+ return walk(current[part], index + 1);
3258
+ };
3259
+ return walk(obj, 0);
2287
3260
  }
2288
- function hasNonEmptyValue(docs, fieldPath, options) {
2289
- var e_2, _a;
3261
+ function inferIdFieldStorageTypeFromDocs(docs, fieldPath) {
3262
+ var e_1, _a, e_2, _b;
2290
3263
  if (!Array.isArray(docs) || !fieldPath) {
2291
- return false;
3264
+ return 'unknown';
2292
3265
  }
2293
- var usePath = fieldPath.includes('.');
3266
+ var sawString = false;
2294
3267
  try {
2295
3268
  for (var docs_1 = __values(docs), docs_1_1 = docs_1.next(); !docs_1_1.done; docs_1_1 = docs_1.next()) {
2296
3269
  var doc = docs_1_1.value;
2297
- var value = usePath ? getValueAtPath(doc, fieldPath) : doc === null || doc === void 0 ? void 0 : doc[fieldPath];
2298
- if ((options === null || options === void 0 ? void 0 : options.treatObjectLikeAsEmpty) && isDisplayObjectLike(value)) {
2299
- continue;
3270
+ var value = fieldPath.includes('.')
3271
+ ? getValueAtPath(doc, fieldPath)
3272
+ : doc === null || doc === void 0 ? void 0 : doc[fieldPath];
3273
+ var queue = Array.isArray(value) ? value : [value];
3274
+ try {
3275
+ for (var queue_1 = (e_2 = void 0, __values(queue)), queue_1_1 = queue_1.next(); !queue_1_1.done; queue_1_1 = queue_1.next()) {
3276
+ var entry = queue_1_1.value;
3277
+ if (entry === null || entry === undefined) {
3278
+ continue;
3279
+ }
3280
+ if (isMongoObjectId(entry)) {
3281
+ return 'objectId';
3282
+ }
3283
+ if (typeof entry === 'string' && entry.trim()) {
3284
+ sawString = true;
3285
+ }
3286
+ }
2300
3287
  }
2301
- if (!isEmptyDisplayValue(value)) {
2302
- return true;
3288
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
3289
+ finally {
3290
+ try {
3291
+ if (queue_1_1 && !queue_1_1.done && (_b = queue_1.return)) _b.call(queue_1);
3292
+ }
3293
+ finally { if (e_2) throw e_2.error; }
2303
3294
  }
2304
3295
  }
2305
3296
  }
2306
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
3297
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2307
3298
  finally {
2308
3299
  try {
2309
3300
  if (docs_1_1 && !docs_1_1.done && (_a = docs_1.return)) _a.call(docs_1);
2310
3301
  }
2311
- finally { if (e_2) throw e_2.error; }
3302
+ finally { if (e_1) throw e_1.error; }
2312
3303
  }
2313
- return false;
3304
+ return sawString ? 'string' : 'unknown';
2314
3305
  }
2315
- function collectFieldCandidates(docs) {
2316
- var candidates = new Map();
2317
- if (!Array.isArray(docs)) {
2318
- return candidates;
3306
+ function normalizeIdsForTargetField(ids, targetDocs, targetFieldPath, targetFieldTypeOverride) {
3307
+ if (!Array.isArray(ids) || !ids.length) {
3308
+ return [];
2319
3309
  }
2320
- var addCandidate = function (path, value) {
2321
- if (!path) {
3310
+ var targetType = targetFieldTypeOverride
3311
+ || inferIdFieldStorageTypeFromDocs(targetDocs || [], targetFieldPath);
3312
+ var normalized = [];
3313
+ var seenStrings = new Set();
3314
+ var seenObjectIds = new Set();
3315
+ var pushString = function (value) {
3316
+ var text = String(value || '').trim();
3317
+ if (!text || seenStrings.has(text)) {
2322
3318
  return;
2323
3319
  }
2324
- var entry = candidates.get(path) || {
2325
- nonEmpty: 0,
2326
- objectLike: 0,
2327
- normalized: normalizeFieldMatchKey(path)
2328
- };
2329
- if (!isEmptyDisplayValue(value)) {
2330
- entry.nonEmpty += 1;
3320
+ seenStrings.add(text);
3321
+ normalized.push(text);
3322
+ };
3323
+ var pushObjectId = function (value) {
3324
+ if (!isMongoObjectId(value)) {
3325
+ return;
2331
3326
  }
2332
- if (isDisplayObjectLike(value)) {
3327
+ var hex = typeof value.toHexString === 'function' ? value.toHexString() : String(value || '');
3328
+ if (!hex || seenObjectIds.has(hex)) {
3329
+ return;
3330
+ }
3331
+ seenObjectIds.add(hex);
3332
+ normalized.push(value);
3333
+ };
3334
+ ids.forEach(function (value) {
3335
+ if (value === null || value === undefined) {
3336
+ return;
3337
+ }
3338
+ if (targetType === 'string') {
3339
+ if (isMongoObjectId(value)) {
3340
+ var hex = typeof value.toHexString === 'function' ? value.toHexString() : String(value || '');
3341
+ pushString(hex);
3342
+ return;
3343
+ }
3344
+ pushString(value);
3345
+ return;
3346
+ }
3347
+ if (targetType === 'objectId') {
3348
+ if (isMongoObjectId(value)) {
3349
+ pushObjectId(value);
3350
+ return;
3351
+ }
3352
+ if (typeof value === 'string' && isObjectIdString(value)) {
3353
+ try {
3354
+ pushObjectId(new mongodb_1.ObjectId(value));
3355
+ }
3356
+ catch (_a) {
3357
+ return;
3358
+ }
3359
+ }
3360
+ return;
3361
+ }
3362
+ if (isMongoObjectId(value)) {
3363
+ pushObjectId(value);
3364
+ var hex = typeof value.toHexString === 'function' ? value.toHexString() : String(value || '');
3365
+ if (hex) {
3366
+ pushString(hex);
3367
+ }
3368
+ return;
3369
+ }
3370
+ if (typeof value === 'string' && isObjectIdString(value)) {
3371
+ try {
3372
+ pushObjectId(new mongodb_1.ObjectId(value));
3373
+ }
3374
+ catch (_b) {
3375
+ // Ignore invalid object id conversions.
3376
+ }
3377
+ pushString(value);
3378
+ return;
3379
+ }
3380
+ pushString(value);
3381
+ });
3382
+ return normalized;
3383
+ }
3384
+ function normalizeLookupKeyValue(value) {
3385
+ if (value === null || value === undefined) {
3386
+ return '';
3387
+ }
3388
+ if (isMongoObjectId(value)) {
3389
+ return typeof value.toHexString === 'function' ? value.toHexString() : String(value);
3390
+ }
3391
+ if (typeof value === 'string') {
3392
+ return value.trim();
3393
+ }
3394
+ return '';
3395
+ }
3396
+ function collectTopLevelIdFieldValues(docs, options) {
3397
+ var e_3, _a, e_4, _b;
3398
+ if (!Array.isArray(docs) || !docs.length) {
3399
+ return [];
3400
+ }
3401
+ var maxFields = typeof (options === null || options === void 0 ? void 0 : options.maxFields) === 'number'
3402
+ ? Math.max(options.maxFields, 0)
3403
+ : AI_ASSISTANT_ID_DISPLAY_LOOKUP_MAX_FIELDS;
3404
+ var maxIds = typeof (options === null || options === void 0 ? void 0 : options.maxIds) === 'number'
3405
+ ? Math.max(options.maxIds, 0)
3406
+ : AI_ASSISTANT_ID_DISPLAY_LOOKUP_MAX_IDS;
3407
+ var fieldMap = new Map();
3408
+ try {
3409
+ for (var docs_2 = __values(docs), docs_2_1 = docs_2.next(); !docs_2_1.done; docs_2_1 = docs_2.next()) {
3410
+ var doc = docs_2_1.value;
3411
+ if (!doc || typeof doc !== 'object') {
3412
+ continue;
3413
+ }
3414
+ var keys = Object.keys(doc);
3415
+ var _loop_3 = function (key) {
3416
+ if (!key || key === '_id' || key === '__v') {
3417
+ return "continue";
3418
+ }
3419
+ if (!isAssistantIdField(key)) {
3420
+ return "continue";
3421
+ }
3422
+ var value = doc[key];
3423
+ var values = Array.isArray(value) ? value : [value];
3424
+ if (!fieldMap.has(key)) {
3425
+ if (maxFields && fieldMap.size >= maxFields) {
3426
+ return "continue";
3427
+ }
3428
+ fieldMap.set(key, new Set());
3429
+ }
3430
+ var bucket = fieldMap.get(key);
3431
+ if (!bucket) {
3432
+ return "continue";
3433
+ }
3434
+ values.forEach(function (entry) {
3435
+ if (entry === null || entry === undefined) {
3436
+ return;
3437
+ }
3438
+ if (bucket.size >= maxIds) {
3439
+ return;
3440
+ }
3441
+ bucket.add(entry);
3442
+ });
3443
+ };
3444
+ try {
3445
+ for (var keys_1 = (e_4 = void 0, __values(keys)), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
3446
+ var key = keys_1_1.value;
3447
+ _loop_3(key);
3448
+ }
3449
+ }
3450
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
3451
+ finally {
3452
+ try {
3453
+ if (keys_1_1 && !keys_1_1.done && (_b = keys_1.return)) _b.call(keys_1);
3454
+ }
3455
+ finally { if (e_4) throw e_4.error; }
3456
+ }
3457
+ }
3458
+ }
3459
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
3460
+ finally {
3461
+ try {
3462
+ if (docs_2_1 && !docs_2_1.done && (_a = docs_2.return)) _a.call(docs_2);
3463
+ }
3464
+ finally { if (e_3) throw e_3.error; }
3465
+ }
3466
+ return Array.from(fieldMap.entries()).map(function (_a) {
3467
+ var _b = __read(_a, 2), field = _b[0], values = _b[1];
3468
+ return ({
3469
+ field: field,
3470
+ values: Array.from(values)
3471
+ });
3472
+ });
3473
+ }
3474
+ function resolveLookupDisplayField(baseToken, probeDocs, schemaFields) {
3475
+ var e_5, _a, e_6, _b;
3476
+ var normalizedBase = normalizeOptionalString(baseToken);
3477
+ if (!normalizedBase) {
3478
+ return null;
3479
+ }
3480
+ var candidates = buildNameLookupFields(normalizedBase, probeDocs || []);
3481
+ var schema = Array.isArray(schemaFields) ? schemaFields : [];
3482
+ if (schema.length) {
3483
+ var schemaCandidates = candidates.filter(function (candidate) { return schema.includes(candidate); });
3484
+ if (schemaCandidates.length) {
3485
+ try {
3486
+ for (var schemaCandidates_1 = __values(schemaCandidates), schemaCandidates_1_1 = schemaCandidates_1.next(); !schemaCandidates_1_1.done; schemaCandidates_1_1 = schemaCandidates_1.next()) {
3487
+ var candidate = schemaCandidates_1_1.value;
3488
+ if (hasNonEmptyValue(probeDocs || [], candidate, { treatObjectLikeAsEmpty: true })) {
3489
+ return candidate;
3490
+ }
3491
+ }
3492
+ }
3493
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
3494
+ finally {
3495
+ try {
3496
+ if (schemaCandidates_1_1 && !schemaCandidates_1_1.done && (_a = schemaCandidates_1.return)) _a.call(schemaCandidates_1);
3497
+ }
3498
+ finally { if (e_5) throw e_5.error; }
3499
+ }
3500
+ return schemaCandidates[0];
3501
+ }
3502
+ }
3503
+ try {
3504
+ for (var candidates_1 = __values(candidates), candidates_1_1 = candidates_1.next(); !candidates_1_1.done; candidates_1_1 = candidates_1.next()) {
3505
+ var candidate = candidates_1_1.value;
3506
+ if (hasNonEmptyValue(probeDocs || [], candidate, { treatObjectLikeAsEmpty: true })) {
3507
+ return candidate;
3508
+ }
3509
+ }
3510
+ }
3511
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
3512
+ finally {
3513
+ try {
3514
+ if (candidates_1_1 && !candidates_1_1.done && (_b = candidates_1.return)) _b.call(candidates_1);
3515
+ }
3516
+ finally { if (e_6) throw e_6.error; }
3517
+ }
3518
+ return candidates.length ? candidates[0] : null;
3519
+ }
3520
+ function resolveLookupMappingsForField(field, mappings) {
3521
+ var normalizedField = normalizeLookupPath(field);
3522
+ if (!normalizedField) {
3523
+ return [];
3524
+ }
3525
+ return mappings.filter(function (mapping) { return normalizeLookupPath(mapping.localKey) === normalizedField; });
3526
+ }
3527
+ function applyIdLookupDisplayEnrichment(params) {
3528
+ return __awaiter(this, void 0, void 0, function () {
3529
+ var docs, collection, db, dbName, idClient, idCustomer, isSuperAdmin, idFields, lookupMappings, allCollections, collectionProbeCache, collectionSchemaCache, lookupMeta, enrichedDocs, _loop_4, idFields_1, idFields_1_1, fieldEntry, e_7_1;
3530
+ var e_7, _a;
3531
+ return __generator(this, function (_b) {
3532
+ switch (_b.label) {
3533
+ case 0:
3534
+ docs = params.docs, collection = params.collection, db = params.db, dbName = params.dbName, idClient = params.idClient, idCustomer = params.idCustomer, isSuperAdmin = params.isSuperAdmin;
3535
+ if (!Array.isArray(docs) || !docs.length) {
3536
+ return [2 /*return*/, { docs: docs }];
3537
+ }
3538
+ idFields = collectTopLevelIdFieldValues(docs, {
3539
+ maxFields: AI_ASSISTANT_ID_DISPLAY_LOOKUP_MAX_FIELDS,
3540
+ maxIds: AI_ASSISTANT_ID_DISPLAY_LOOKUP_MAX_IDS
3541
+ });
3542
+ if (!idFields.length) {
3543
+ return [2 /*return*/, { docs: docs }];
3544
+ }
3545
+ lookupMappings = getCollectionLookupMappings(collection);
3546
+ return [4 /*yield*/, listAssistantCollections(db, dbName)];
3547
+ case 1:
3548
+ allCollections = _b.sent();
3549
+ collectionProbeCache = new Map();
3550
+ collectionSchemaCache = new Map();
3551
+ lookupMeta = [];
3552
+ enrichedDocs = docs.map(function (doc) { return (__assign({}, doc)); });
3553
+ _loop_4 = function (fieldEntry) {
3554
+ var values, baseToken, mappingMatches, candidateCollections, filteredCandidates, _loop_5, filteredCandidates_1, filteredCandidates_1_1, candidate, state_3, e_8_1;
3555
+ var e_8, _c;
3556
+ return __generator(this, function (_d) {
3557
+ switch (_d.label) {
3558
+ case 0:
3559
+ values = fieldEntry.values || [];
3560
+ if (!values.length) {
3561
+ return [2 /*return*/, "continue"];
3562
+ }
3563
+ baseToken = normalizeIdFieldBase(fieldEntry.field);
3564
+ if (!baseToken) {
3565
+ return [2 /*return*/, "continue"];
3566
+ }
3567
+ mappingMatches = resolveLookupMappingsForField(fieldEntry.field, lookupMappings);
3568
+ candidateCollections = mappingMatches.length
3569
+ ? mappingMatches.map(function (entry) { return entry.lookupCollection; })
3570
+ : resolveIdLookupCandidates(baseToken, allCollections);
3571
+ filteredCandidates = candidateCollections
3572
+ .filter(function (candidate) { return !!candidate; })
3573
+ .filter(function (candidate) { return candidate !== collection; })
3574
+ .filter(function (candidate) { return !candidate.endsWith('.versions'); })
3575
+ .filter(function (candidate) { return isSuperAdmin || !AI_ASSISTANT_BLOCKED_COLLECTIONS.has(candidate); })
3576
+ .slice(0, AI_ASSISTANT_ID_DISPLAY_LOOKUP_MAX_COLLECTIONS);
3577
+ if (!filteredCandidates.length) {
3578
+ return [2 /*return*/, "continue"];
3579
+ }
3580
+ _loop_5 = function (candidate) {
3581
+ var probeDocs, candidateHasClientScope, _e, schemaFields, nameField, mapping, lookupKey, idsForQuery, query, candidateHasClientScope, _f, lookupDocs, nameMap, displayField;
3582
+ var _g, _h;
3583
+ return __generator(this, function (_j) {
3584
+ switch (_j.label) {
3585
+ case 0:
3586
+ probeDocs = collectionProbeCache.get(candidate);
3587
+ if (!!probeDocs) return [3 /*break*/, 5];
3588
+ if (!idClient) return [3 /*break*/, 2];
3589
+ return [4 /*yield*/, collectionHasClientIndex(db, dbName, candidate)];
3590
+ case 1:
3591
+ _e = _j.sent();
3592
+ return [3 /*break*/, 3];
3593
+ case 2:
3594
+ _e = false;
3595
+ _j.label = 3;
3596
+ case 3:
3597
+ candidateHasClientScope = _e;
3598
+ return [4 /*yield*/, fetchAssistantProbeDocs({
3599
+ db: db,
3600
+ collection: candidate,
3601
+ idClient: idClient,
3602
+ idCustomer: idCustomer,
3603
+ isSuperAdmin: isSuperAdmin,
3604
+ includeClientScope: candidateHasClientScope
3605
+ })];
3606
+ case 4:
3607
+ probeDocs = _j.sent();
3608
+ collectionProbeCache.set(candidate, probeDocs);
3609
+ _j.label = 5;
3610
+ case 5:
3611
+ schemaFields = collectionSchemaCache.get(candidate)
3612
+ || getCollectionSchemaFieldNames(candidate);
3613
+ collectionSchemaCache.set(candidate, schemaFields);
3614
+ nameField = resolveLookupDisplayField(baseToken, probeDocs, schemaFields);
3615
+ if (!nameField) {
3616
+ return [2 /*return*/, "continue"];
3617
+ }
3618
+ mapping = mappingMatches.find(function (entry) { return entry.lookupCollection === candidate; });
3619
+ lookupKey = normalizeOptionalString(mapping === null || mapping === void 0 ? void 0 : mapping.lookupKey) || '_id';
3620
+ idsForQuery = normalizeIdsForTargetField(values, probeDocs, lookupKey);
3621
+ if (!idsForQuery.length) {
3622
+ return [2 /*return*/, "continue"];
3623
+ }
3624
+ query = (_g = {}, _g[lookupKey] = { $in: idsForQuery }, _g);
3625
+ if (!!isSuperAdmin) return [3 /*break*/, 9];
3626
+ if (!idClient) return [3 /*break*/, 7];
3627
+ return [4 /*yield*/, collectionHasClientIndex(db, dbName, candidate)];
3628
+ case 6:
3629
+ _f = _j.sent();
3630
+ return [3 /*break*/, 8];
3631
+ case 7:
3632
+ _f = false;
3633
+ _j.label = 8;
3634
+ case 8:
3635
+ candidateHasClientScope = _f;
3636
+ if (candidateHasClientScope) {
3637
+ query = applyClientScopeFilter(query, idClient, isSuperAdmin);
3638
+ }
3639
+ query = applyCustomerScopeFilter(query, candidate, idCustomer, isSuperAdmin);
3640
+ _j.label = 9;
3641
+ case 9: return [4 /*yield*/, db.collection(candidate).find(query, {
3642
+ projection: (_h = {}, _h[lookupKey] = 1, _h[nameField] = 1, _h),
3643
+ limit: AI_ASSISTANT_ID_DISPLAY_LOOKUP_MAX_IDS,
3644
+ readPreference: AI_ASSISTANT_READ_PREFERENCE
3645
+ }).toArray()];
3646
+ case 10:
3647
+ lookupDocs = _j.sent();
3648
+ if (!lookupDocs.length) {
3649
+ return [2 /*return*/, "continue"];
3650
+ }
3651
+ nameMap = new Map();
3652
+ lookupDocs.forEach(function (doc) {
3653
+ var _a, _b;
3654
+ var key = normalizeLookupKeyValue((_a = getValueAtPath(doc, lookupKey)) !== null && _a !== void 0 ? _a : doc === null || doc === void 0 ? void 0 : doc[lookupKey]);
3655
+ if (!key) {
3656
+ return;
3657
+ }
3658
+ var nameValue = (_b = getValueAtPath(doc, nameField)) !== null && _b !== void 0 ? _b : doc === null || doc === void 0 ? void 0 : doc[nameField];
3659
+ if (isEmptyDisplayValue(nameValue)) {
3660
+ return;
3661
+ }
3662
+ if (!nameMap.has(key)) {
3663
+ nameMap.set(key, nameValue);
3664
+ }
3665
+ });
3666
+ if (!nameMap.size) {
3667
+ return [2 /*return*/, "continue"];
3668
+ }
3669
+ displayField = baseToken;
3670
+ enrichedDocs = enrichedDocs.map(function (doc) {
3671
+ var _a;
3672
+ var rawValue = doc === null || doc === void 0 ? void 0 : doc[fieldEntry.field];
3673
+ if (rawValue === undefined || rawValue === null) {
3674
+ return doc;
3675
+ }
3676
+ if (!displayField || !isEmptyDisplayValue(doc === null || doc === void 0 ? void 0 : doc[displayField])) {
3677
+ return doc;
3678
+ }
3679
+ var valuesToResolve = Array.isArray(rawValue) ? rawValue : [rawValue];
3680
+ var resolved = valuesToResolve
3681
+ .map(function (value) { return nameMap.get(normalizeLookupKeyValue(value)); })
3682
+ .filter(function (value) { return !isEmptyDisplayValue(value); });
3683
+ if (!resolved.length) {
3684
+ return doc;
3685
+ }
3686
+ return __assign(__assign({}, doc), (_a = {}, _a[displayField] = resolved.length === 1 ? resolved[0] : resolved, _a));
3687
+ });
3688
+ lookupMeta.push({
3689
+ field: fieldEntry.field,
3690
+ displayField: displayField,
3691
+ collection: candidate,
3692
+ nameField: nameField,
3693
+ idCount: values.length,
3694
+ matched: nameMap.size,
3695
+ strategy: mapping ? 'schema' : 'token'
3696
+ });
3697
+ return [2 /*return*/, "break"];
3698
+ }
3699
+ });
3700
+ };
3701
+ _d.label = 1;
3702
+ case 1:
3703
+ _d.trys.push([1, 6, 7, 8]);
3704
+ filteredCandidates_1 = (e_8 = void 0, __values(filteredCandidates)), filteredCandidates_1_1 = filteredCandidates_1.next();
3705
+ _d.label = 2;
3706
+ case 2:
3707
+ if (!!filteredCandidates_1_1.done) return [3 /*break*/, 5];
3708
+ candidate = filteredCandidates_1_1.value;
3709
+ return [5 /*yield**/, _loop_5(candidate)];
3710
+ case 3:
3711
+ state_3 = _d.sent();
3712
+ if (state_3 === "break")
3713
+ return [3 /*break*/, 5];
3714
+ _d.label = 4;
3715
+ case 4:
3716
+ filteredCandidates_1_1 = filteredCandidates_1.next();
3717
+ return [3 /*break*/, 2];
3718
+ case 5: return [3 /*break*/, 8];
3719
+ case 6:
3720
+ e_8_1 = _d.sent();
3721
+ e_8 = { error: e_8_1 };
3722
+ return [3 /*break*/, 8];
3723
+ case 7:
3724
+ try {
3725
+ if (filteredCandidates_1_1 && !filteredCandidates_1_1.done && (_c = filteredCandidates_1.return)) _c.call(filteredCandidates_1);
3726
+ }
3727
+ finally { if (e_8) throw e_8.error; }
3728
+ return [7 /*endfinally*/];
3729
+ case 8: return [2 /*return*/];
3730
+ }
3731
+ });
3732
+ };
3733
+ _b.label = 2;
3734
+ case 2:
3735
+ _b.trys.push([2, 7, 8, 9]);
3736
+ idFields_1 = __values(idFields), idFields_1_1 = idFields_1.next();
3737
+ _b.label = 3;
3738
+ case 3:
3739
+ if (!!idFields_1_1.done) return [3 /*break*/, 6];
3740
+ fieldEntry = idFields_1_1.value;
3741
+ return [5 /*yield**/, _loop_4(fieldEntry)];
3742
+ case 4:
3743
+ _b.sent();
3744
+ _b.label = 5;
3745
+ case 5:
3746
+ idFields_1_1 = idFields_1.next();
3747
+ return [3 /*break*/, 3];
3748
+ case 6: return [3 /*break*/, 9];
3749
+ case 7:
3750
+ e_7_1 = _b.sent();
3751
+ e_7 = { error: e_7_1 };
3752
+ return [3 /*break*/, 9];
3753
+ case 8:
3754
+ try {
3755
+ if (idFields_1_1 && !idFields_1_1.done && (_a = idFields_1.return)) _a.call(idFields_1);
3756
+ }
3757
+ finally { if (e_7) throw e_7.error; }
3758
+ return [7 /*endfinally*/];
3759
+ case 9:
3760
+ if (!lookupMeta.length) {
3761
+ return [2 /*return*/, { docs: enrichedDocs }];
3762
+ }
3763
+ return [2 /*return*/, {
3764
+ docs: enrichedDocs,
3765
+ meta: {
3766
+ attempted: true,
3767
+ used: true,
3768
+ lookups: lookupMeta
3769
+ }
3770
+ }];
3771
+ }
3772
+ });
3773
+ });
3774
+ }
3775
+ function hasNonEmptyValue(docs, fieldPath, options) {
3776
+ var e_9, _a;
3777
+ if (!Array.isArray(docs) || !fieldPath) {
3778
+ return false;
3779
+ }
3780
+ var usePath = fieldPath.includes('.');
3781
+ try {
3782
+ for (var docs_3 = __values(docs), docs_3_1 = docs_3.next(); !docs_3_1.done; docs_3_1 = docs_3.next()) {
3783
+ var doc = docs_3_1.value;
3784
+ var value = usePath ? getValueAtPath(doc, fieldPath) : doc === null || doc === void 0 ? void 0 : doc[fieldPath];
3785
+ if ((options === null || options === void 0 ? void 0 : options.treatObjectLikeAsEmpty) && isDisplayObjectLike(value)) {
3786
+ continue;
3787
+ }
3788
+ if (!isEmptyDisplayValue(value)) {
3789
+ return true;
3790
+ }
3791
+ }
3792
+ }
3793
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
3794
+ finally {
3795
+ try {
3796
+ if (docs_3_1 && !docs_3_1.done && (_a = docs_3.return)) _a.call(docs_3);
3797
+ }
3798
+ finally { if (e_9) throw e_9.error; }
3799
+ }
3800
+ return false;
3801
+ }
3802
+ function collectFieldCandidates(docs) {
3803
+ var candidates = new Map();
3804
+ if (!Array.isArray(docs)) {
3805
+ return candidates;
3806
+ }
3807
+ var addCandidate = function (path, value) {
3808
+ if (!path) {
3809
+ return;
3810
+ }
3811
+ var entry = candidates.get(path) || {
3812
+ nonEmpty: 0,
3813
+ objectLike: 0,
3814
+ normalized: normalizeFieldMatchKey(path)
3815
+ };
3816
+ if (!isEmptyDisplayValue(value)) {
3817
+ entry.nonEmpty += 1;
3818
+ }
3819
+ if (isDisplayObjectLike(value)) {
2333
3820
  entry.objectLike += 1;
2334
3821
  }
2335
3822
  candidates.set(path, entry);
@@ -2344,6 +3831,17 @@ function collectFieldCandidates(docs) {
2344
3831
  }
2345
3832
  var value = doc[key];
2346
3833
  addCandidate(key, value);
3834
+ if (Array.isArray(value)) {
3835
+ var nestedSamples = value.filter(function (entry) { return isPlainObject(entry); }).slice(0, 3);
3836
+ nestedSamples.forEach(function (entry) {
3837
+ Object.keys(entry).slice(0, 50).forEach(function (nestedKey) {
3838
+ if (!nestedKey) {
3839
+ return;
3840
+ }
3841
+ addCandidate("".concat(key, ".").concat(nestedKey), entry[nestedKey]);
3842
+ });
3843
+ });
3844
+ }
2347
3845
  if (isPlainObject(value) && !isMongoObjectId(value) && !(value instanceof Date)) {
2348
3846
  var nestedKeys = Object.keys(value).slice(0, 50);
2349
3847
  nestedKeys.forEach(function (nestedKey) {
@@ -2357,7 +3855,7 @@ function collectFieldCandidates(docs) {
2357
3855
  });
2358
3856
  return candidates;
2359
3857
  }
2360
- function resolveFieldAliases(docs, requestedFields) {
3858
+ function resolveFieldAliases(docs, requestedFields, schemaFields) {
2361
3859
  var aliases = {};
2362
3860
  if (!Array.isArray(docs) || !requestedFields.length) {
2363
3861
  return aliases;
@@ -2367,11 +3865,24 @@ function resolveFieldAliases(docs, requestedFields) {
2367
3865
  return aliases;
2368
3866
  }
2369
3867
  var candidates = collectFieldCandidates(docs);
3868
+ var schemaFieldList = Array.isArray(schemaFields) ? schemaFields.filter(Boolean) : [];
3869
+ var candidateFieldList = schemaFieldList.length ? schemaFieldList : Array.from(candidates.keys());
2370
3870
  missing.forEach(function (field) {
2371
3871
  var normalizedRequested = normalizeFieldMatchKey(field);
2372
3872
  if (!normalizedRequested) {
2373
3873
  return;
2374
3874
  }
3875
+ var requestedBaseTokens = tokenizeFieldKey(field);
3876
+ var requestedHasType = requestedBaseTokens.includes('type');
3877
+ var hasNonTypeCandidate = requestedBaseTokens.length
3878
+ ? candidateFieldList.some(function (candidateField) {
3879
+ var tokens = tokenizeFieldKey(candidateField);
3880
+ if (tokens.includes('type')) {
3881
+ return false;
3882
+ }
3883
+ return requestedBaseTokens.some(function (token) { return tokens.includes(token); });
3884
+ })
3885
+ : false;
2375
3886
  var bestPath = '';
2376
3887
  var bestScore = 0;
2377
3888
  candidates.forEach(function (stats, path) {
@@ -2381,6 +3892,13 @@ function resolveFieldAliases(docs, requestedFields) {
2381
3892
  if (isAssistantIdField(path)) {
2382
3893
  return;
2383
3894
  }
3895
+ var candidateTokens = tokenizeFieldKey(path);
3896
+ if (isUnsafeFieldAlias(requestedBaseTokens, candidateTokens)) {
3897
+ return;
3898
+ }
3899
+ if (!requestedHasType && candidateTokens.includes('type') && hasNonTypeCandidate) {
3900
+ return;
3901
+ }
2384
3902
  var normalizedCandidate = stats.normalized || normalizeFieldMatchKey(path);
2385
3903
  if (!normalizedCandidate) {
2386
3904
  return;
@@ -2393,11 +3911,17 @@ function resolveFieldAliases(docs, requestedFields) {
2393
3911
  score = 70;
2394
3912
  }
2395
3913
  else {
2396
- var candidateTokens_1 = tokenizeFieldKey(path);
2397
- var requestedTokens = tokenizeFieldKey(field);
2398
- var overlap = requestedTokens.filter(function (token) { return candidateTokens_1.includes(token); }).length;
3914
+ var requestedTokens = expandFieldTokens(requestedBaseTokens);
3915
+ var overlap = requestedTokens.filter(function (token) { return candidateTokens.includes(token); }).length;
3916
+ var baseOverlap = requestedBaseTokens.filter(function (token) { return candidateTokens.includes(token); }).length;
2399
3917
  if (overlap > 0) {
2400
- score = 40 + overlap * 5;
3918
+ score = 40 + overlap * 10;
3919
+ if (baseOverlap === 0) {
3920
+ score += 10;
3921
+ }
3922
+ if (requestedBaseTokens.length <= 2) {
3923
+ score += 10;
3924
+ }
2401
3925
  }
2402
3926
  }
2403
3927
  var objectRatio = stats.objectLike / Math.max(stats.nonEmpty, 1);
@@ -2462,45 +3986,156 @@ function resolveProjectionRequestedFields(projection) {
2462
3986
  }
2463
3987
  return keys.filter(function (key) { return !isAssistantIdField(key); });
2464
3988
  }
2465
- function formatDisplayColumnName(column) {
2466
- var trimmed = String(column || '').trim();
2467
- if (!trimmed) {
2468
- return '';
2469
- }
2470
- if (trimmed === '_id') {
2471
- return 'id';
2472
- }
2473
- if (trimmed === '_group') {
2474
- return 'Group';
2475
- }
2476
- var normalized = trimmed.replace(/[\s_]+/g, '').toLowerCase();
2477
- if (normalized === 'createdat') {
2478
- return 'Created At';
3989
+ function isInclusiveProjection(projection) {
3990
+ if (!projection || typeof projection !== 'object') {
3991
+ return false;
2479
3992
  }
2480
- if (normalized === 'updatedat') {
2481
- return 'Updated At';
3993
+ var keys = Object.keys(projection);
3994
+ if (!keys.length) {
3995
+ return false;
2482
3996
  }
2483
- var parts = trimmed.split('.');
2484
- var base = parts[parts.length - 1] || trimmed;
2485
- if ((base === 'name' || base === 'title' || base === 'label') && parts.length > 1) {
2486
- return parts[parts.length - 2]
2487
- .replace(/[_-]+/g, ' ')
2488
- .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
2489
- .replace(/\s+/g, ' ')
2490
- .trim()
2491
- .replace(/\b\w/g, function (char) { return char.toUpperCase(); });
3997
+ var hasInclude = false;
3998
+ var hasExclude = false;
3999
+ keys.forEach(function (key) {
4000
+ var value = projection[key];
4001
+ if (value === 0 || value === false) {
4002
+ hasExclude = true;
4003
+ }
4004
+ else if (value === 1 || value === true) {
4005
+ hasInclude = true;
4006
+ }
4007
+ });
4008
+ return hasInclude && !hasExclude;
4009
+ }
4010
+ function expandProjectionWithAliases(projection, aliases) {
4011
+ if (!projection || !isInclusiveProjection(projection) || !aliases || !Object.keys(aliases).length) {
4012
+ return projection;
2492
4013
  }
2493
- return base
2494
- .replace(/[_-]+/g, ' ')
2495
- .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
2496
- .replace(/\s+/g, ' ')
2497
- .trim()
2498
- .replace(/\b\w/g, function (char) { return char.toUpperCase(); });
4014
+ var next = __assign({}, projection);
4015
+ Object.keys(aliases).forEach(function (target) {
4016
+ var source = aliases[target];
4017
+ if (!source) {
4018
+ return;
4019
+ }
4020
+ if (!Object.prototype.hasOwnProperty.call(next, source)) {
4021
+ next[source] = 1;
4022
+ }
4023
+ });
4024
+ return next;
2499
4025
  }
2500
- function truncateDisplayText(value, maxLength) {
2501
- if (maxLength === void 0) { maxLength = AI_ASSISTANT_DISPLAY_STRING_LIMIT; }
2502
- if (!value) {
2503
- return value;
4026
+ function collectQueryFieldPaths(value, fields) {
4027
+ if (!value || typeof value !== 'object' || value instanceof Date || value instanceof RegExp || isMongoObjectId(value)) {
4028
+ return;
4029
+ }
4030
+ if (Array.isArray(value)) {
4031
+ value.forEach(function (entry) { return collectQueryFieldPaths(entry, fields); });
4032
+ return;
4033
+ }
4034
+ Object.keys(value).forEach(function (key) {
4035
+ var entry = value[key];
4036
+ if (key.startsWith('$')) {
4037
+ collectQueryFieldPaths(entry, fields);
4038
+ return;
4039
+ }
4040
+ fields.add(key);
4041
+ if (entry && typeof entry === 'object' && !Array.isArray(entry) && !isMongoObjectId(entry) && !(entry instanceof Date)) {
4042
+ var nestedKeys = Object.keys(entry).filter(function (nested) { return !nested.startsWith('$'); });
4043
+ nestedKeys.forEach(function (nested) {
4044
+ fields.add("".concat(key, ".").concat(nested));
4045
+ });
4046
+ }
4047
+ });
4048
+ }
4049
+ function extractQueryFieldPaths(query) {
4050
+ var fields = new Set();
4051
+ collectQueryFieldPaths(query, fields);
4052
+ return Array.from(fields).filter(Boolean);
4053
+ }
4054
+ function replaceFieldPathDeep(value, fromField, toField) {
4055
+ if (Array.isArray(value)) {
4056
+ return value.map(function (entry) { return replaceFieldPathDeep(entry, fromField, toField); });
4057
+ }
4058
+ if (value instanceof Date || isMongoObjectId(value)) {
4059
+ return value;
4060
+ }
4061
+ if (value && typeof value === 'object') {
4062
+ var next_1 = {};
4063
+ Object.keys(value).forEach(function (key) {
4064
+ var nextKey = key === fromField ? toField : key;
4065
+ next_1[nextKey] = replaceFieldPathDeep(value[key], fromField, toField);
4066
+ });
4067
+ return next_1;
4068
+ }
4069
+ if (typeof value === 'string') {
4070
+ if (value.startsWith("$".concat(fromField))) {
4071
+ return "$".concat(toField).concat(value.slice(fromField.length + 1));
4072
+ }
4073
+ return value;
4074
+ }
4075
+ return value;
4076
+ }
4077
+ function replaceQueryFieldCondition(query, field, condition) {
4078
+ if (Array.isArray(query)) {
4079
+ return query.map(function (entry) { return replaceQueryFieldCondition(entry, field, condition); });
4080
+ }
4081
+ if (!query || typeof query !== 'object') {
4082
+ return query;
4083
+ }
4084
+ var next = __assign({}, query);
4085
+ Object.keys(next).forEach(function (key) {
4086
+ if (key === field) {
4087
+ next[key] = condition;
4088
+ return;
4089
+ }
4090
+ if (key.startsWith('$')) {
4091
+ next[key] = replaceQueryFieldCondition(next[key], field, condition);
4092
+ return;
4093
+ }
4094
+ if (next[key] && typeof next[key] === 'object') {
4095
+ next[key] = replaceQueryFieldCondition(next[key], field, condition);
4096
+ }
4097
+ });
4098
+ return next;
4099
+ }
4100
+ function formatDisplayColumnName(column) {
4101
+ var trimmed = String(column || '').trim();
4102
+ if (!trimmed) {
4103
+ return '';
4104
+ }
4105
+ if (trimmed === '_id') {
4106
+ return 'id';
4107
+ }
4108
+ if (trimmed === '_group') {
4109
+ return 'Group';
4110
+ }
4111
+ var normalized = trimmed.replace(/[\s_]+/g, '').toLowerCase();
4112
+ if (normalized === 'createdat') {
4113
+ return 'Created At';
4114
+ }
4115
+ if (normalized === 'updatedat') {
4116
+ return 'Updated At';
4117
+ }
4118
+ var parts = trimmed.split('.');
4119
+ var base = parts[parts.length - 1] || trimmed;
4120
+ if ((base === 'name' || base === 'title' || base === 'label') && parts.length > 1) {
4121
+ return parts[parts.length - 2]
4122
+ .replace(/[_-]+/g, ' ')
4123
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
4124
+ .replace(/\s+/g, ' ')
4125
+ .trim()
4126
+ .replace(/\b\w/g, function (char) { return char.toUpperCase(); });
4127
+ }
4128
+ return base
4129
+ .replace(/[_-]+/g, ' ')
4130
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
4131
+ .replace(/\s+/g, ' ')
4132
+ .trim()
4133
+ .replace(/\b\w/g, function (char) { return char.toUpperCase(); });
4134
+ }
4135
+ function truncateDisplayText(value, maxLength) {
4136
+ if (maxLength === void 0) { maxLength = AI_ASSISTANT_DISPLAY_STRING_LIMIT; }
4137
+ if (!value) {
4138
+ return value;
2504
4139
  }
2505
4140
  if (value.length <= maxLength) {
2506
4141
  return value;
@@ -2866,10 +4501,12 @@ function normalizeAssistantAggregatePipeline(pipeline) {
2866
4501
  .map(function (stage) {
2867
4502
  var next = __assign({}, stage);
2868
4503
  if (next.$match && typeof next.$match === 'object') {
2869
- next.$match = applyAssistantNameRegexToQuery(next.$match);
4504
+ var rewritten = rewriteEmbeddedMatchObjects(next.$match);
4505
+ next.$match = applyAssistantNameRegexToQuery(rewritten);
2870
4506
  }
2871
4507
  if (next.$geoNear && typeof next.$geoNear === 'object' && next.$geoNear.query) {
2872
- next.$geoNear = __assign(__assign({}, next.$geoNear), { query: applyAssistantNameRegexToQuery(next.$geoNear.query) });
4508
+ var rewritten = rewriteEmbeddedMatchObjects(next.$geoNear.query);
4509
+ next.$geoNear = __assign(__assign({}, next.$geoNear), { query: applyAssistantNameRegexToQuery(rewritten) });
2873
4510
  }
2874
4511
  return next;
2875
4512
  });
@@ -3000,7 +4637,7 @@ function matchContainsField(value, field) {
3000
4637
  });
3001
4638
  }
3002
4639
  function resolveAggregateCompletionFallback(pipeline) {
3003
- var e_3, _a;
4640
+ var e_10, _a;
3004
4641
  if (!Array.isArray(pipeline)) {
3005
4642
  return null;
3006
4643
  }
@@ -3013,7 +4650,7 @@ function resolveAggregateCompletionFallback(pipeline) {
3013
4650
  }
3014
4651
  var addFields = stage.$addFields;
3015
4652
  try {
3016
- for (var _b = (e_3 = void 0, __values(Object.keys(addFields))), _c = _b.next(); !_c.done; _c = _b.next()) {
4653
+ for (var _b = (e_10 = void 0, __values(Object.keys(addFields))), _c = _b.next(); !_c.done; _c = _b.next()) {
3017
4654
  var key = _c.value;
3018
4655
  if (!isCompletionFieldName(key)) {
3019
4656
  continue;
@@ -3027,12 +4664,12 @@ function resolveAggregateCompletionFallback(pipeline) {
3027
4664
  }
3028
4665
  }
3029
4666
  }
3030
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
4667
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
3031
4668
  finally {
3032
4669
  try {
3033
4670
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3034
4671
  }
3035
- finally { if (e_3) throw e_3.error; }
4672
+ finally { if (e_10) throw e_10.error; }
3036
4673
  }
3037
4674
  if (candidateField) {
3038
4675
  break;
@@ -3188,7 +4825,7 @@ function buildCompletionFallbackSources(field) {
3188
4825
  ]);
3189
4826
  }
3190
4827
  function resolveAggregateCompletionExprFallback(pipeline) {
3191
- var e_4, _a;
4828
+ var e_11, _a;
3192
4829
  if (!Array.isArray(pipeline)) {
3193
4830
  return null;
3194
4831
  }
@@ -3208,7 +4845,7 @@ function resolveAggregateCompletionExprFallback(pipeline) {
3208
4845
  }
3209
4846
  if (!candidateField) {
3210
4847
  try {
3211
- for (var _b = (e_4 = void 0, __values(Object.keys(matchStage))), _c = _b.next(); !_c.done; _c = _b.next()) {
4848
+ for (var _b = (e_11 = void 0, __values(Object.keys(matchStage))), _c = _b.next(); !_c.done; _c = _b.next()) {
3212
4849
  var key = _c.value;
3213
4850
  if (key.startsWith('$')) {
3214
4851
  continue;
@@ -3223,12 +4860,12 @@ function resolveAggregateCompletionExprFallback(pipeline) {
3223
4860
  }
3224
4861
  }
3225
4862
  }
3226
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
4863
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
3227
4864
  finally {
3228
4865
  try {
3229
4866
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3230
4867
  }
3231
- finally { if (e_4) throw e_4.error; }
4868
+ finally { if (e_11) throw e_11.error; }
3232
4869
  }
3233
4870
  }
3234
4871
  if (!candidateField) {
@@ -3398,7 +5035,7 @@ function isRegexMatchCondition(value) {
3398
5035
  return false;
3399
5036
  }
3400
5037
  function findRegexMatchInMatchObject(match, prefix) {
3401
- var e_5, _a, e_6, _b;
5038
+ var e_12, _a, e_13, _b;
3402
5039
  if (prefix === void 0) { prefix = ''; }
3403
5040
  if (Array.isArray(match)) {
3404
5041
  try {
@@ -3410,12 +5047,12 @@ function findRegexMatchInMatchObject(match, prefix) {
3410
5047
  }
3411
5048
  }
3412
5049
  }
3413
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
5050
+ catch (e_12_1) { e_12 = { error: e_12_1 }; }
3414
5051
  finally {
3415
5052
  try {
3416
5053
  if (match_1_1 && !match_1_1.done && (_a = match_1.return)) _a.call(match_1);
3417
5054
  }
3418
- finally { if (e_5) throw e_5.error; }
5055
+ finally { if (e_12) throw e_12.error; }
3419
5056
  }
3420
5057
  return null;
3421
5058
  }
@@ -3424,8 +5061,8 @@ function findRegexMatchInMatchObject(match, prefix) {
3424
5061
  }
3425
5062
  var keys = Object.keys(match);
3426
5063
  try {
3427
- for (var keys_1 = __values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
3428
- var key = keys_1_1.value;
5064
+ for (var keys_2 = __values(keys), keys_2_1 = keys_2.next(); !keys_2_1.done; keys_2_1 = keys_2.next()) {
5065
+ var key = keys_2_1.value;
3429
5066
  var value = match[key];
3430
5067
  if (key.startsWith('$')) {
3431
5068
  var found = findRegexMatchInMatchObject(value, prefix);
@@ -3446,12 +5083,12 @@ function findRegexMatchInMatchObject(match, prefix) {
3446
5083
  }
3447
5084
  }
3448
5085
  }
3449
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
5086
+ catch (e_13_1) { e_13 = { error: e_13_1 }; }
3450
5087
  finally {
3451
5088
  try {
3452
- if (keys_1_1 && !keys_1_1.done && (_b = keys_1.return)) _b.call(keys_1);
5089
+ if (keys_2_1 && !keys_2_1.done && (_b = keys_2.return)) _b.call(keys_2);
3453
5090
  }
3454
- finally { if (e_6) throw e_6.error; }
5091
+ finally { if (e_13) throw e_13.error; }
3455
5092
  }
3456
5093
  return null;
3457
5094
  }
@@ -3500,6 +5137,9 @@ function expandNameFieldCandidates(field) {
3500
5137
  push(withPrefix("".concat(leaf, ".name")));
3501
5138
  push(withPrefix("".concat(leaf, ".label")));
3502
5139
  push(withPrefix("".concat(leaf, ".product")));
5140
+ if (normalized.includes('blend_chemicals')) {
5141
+ ['chemical', 'chemical_name', 'chemicalName', 'product', 'product_name', 'productName'].forEach(push);
5142
+ }
3503
5143
  }
3504
5144
  if (leafLower.includes('customer')) {
3505
5145
  [
@@ -3564,6 +5204,32 @@ function resolveAggregateNameMatchFallback(pipeline) {
3564
5204
  }
3565
5205
  return null;
3566
5206
  }
5207
+ function resolveReadNameMatchFallback(query) {
5208
+ if (!query || typeof query !== 'object') {
5209
+ return null;
5210
+ }
5211
+ var found = findRegexMatchInMatchObject(query);
5212
+ if (!found || !shouldApplyAssistantNameRegex(found.field) || isAssistantIdField(found.field)) {
5213
+ return null;
5214
+ }
5215
+ var fields = expandNameFieldCandidates(found.field);
5216
+ if (fields.length <= 1) {
5217
+ return null;
5218
+ }
5219
+ var baseMatch = stripMatchField(query, found.field);
5220
+ var orConditions = fields.map(function (field) {
5221
+ var _a;
5222
+ return (_a = {}, _a[field] = found.condition, _a);
5223
+ });
5224
+ var nextMatch = isEmptyMatchValue(baseMatch)
5225
+ ? { $or: orConditions }
5226
+ : { $and: [baseMatch, { $or: orConditions }] };
5227
+ return {
5228
+ query: nextMatch,
5229
+ field: found.field,
5230
+ fields: fields
5231
+ };
5232
+ }
3567
5233
  function isEmptyMatchValue(value) {
3568
5234
  if (value === null || value === undefined) {
3569
5235
  return true;
@@ -3605,11 +5271,775 @@ function stripMatchField(match, field) {
3605
5271
  if (!isEmptyMatchValue(stripped)) {
3606
5272
  result[key] = stripped;
3607
5273
  }
3608
- return;
3609
- }
3610
- result[key] = value;
5274
+ return;
5275
+ }
5276
+ result[key] = value;
5277
+ });
5278
+ return result;
5279
+ }
5280
+ function collectMatchFieldsByCondition(match, predicate, prefix) {
5281
+ if (prefix === void 0) { prefix = ''; }
5282
+ var results = [];
5283
+ if (Array.isArray(match)) {
5284
+ match.forEach(function (entry) {
5285
+ results.push.apply(results, __spreadArray([], __read(collectMatchFieldsByCondition(entry, predicate, prefix)), false));
5286
+ });
5287
+ return results;
5288
+ }
5289
+ if (!match || typeof match !== 'object') {
5290
+ return results;
5291
+ }
5292
+ Object.keys(match).forEach(function (key) {
5293
+ var value = match[key];
5294
+ if (key.startsWith('$')) {
5295
+ results.push.apply(results, __spreadArray([], __read(collectMatchFieldsByCondition(value, predicate, prefix)), false));
5296
+ return;
5297
+ }
5298
+ var currentPath = prefix ? "".concat(prefix, ".").concat(key) : key;
5299
+ if (predicate(currentPath, value)) {
5300
+ results.push(currentPath);
5301
+ }
5302
+ if (value && typeof value === 'object') {
5303
+ results.push.apply(results, __spreadArray([], __read(collectMatchFieldsByCondition(value, predicate, currentPath)), false));
5304
+ }
5305
+ });
5306
+ return results;
5307
+ }
5308
+ function findMatchConditionForField(match, targetField, prefix) {
5309
+ var e_14, _a, e_15, _b;
5310
+ if (prefix === void 0) { prefix = ''; }
5311
+ if (!match || typeof match !== 'object') {
5312
+ return undefined;
5313
+ }
5314
+ if (Array.isArray(match)) {
5315
+ try {
5316
+ for (var match_2 = __values(match), match_2_1 = match_2.next(); !match_2_1.done; match_2_1 = match_2.next()) {
5317
+ var entry = match_2_1.value;
5318
+ var found = findMatchConditionForField(entry, targetField, prefix);
5319
+ if (found !== undefined) {
5320
+ return found;
5321
+ }
5322
+ }
5323
+ }
5324
+ catch (e_14_1) { e_14 = { error: e_14_1 }; }
5325
+ finally {
5326
+ try {
5327
+ if (match_2_1 && !match_2_1.done && (_a = match_2.return)) _a.call(match_2);
5328
+ }
5329
+ finally { if (e_14) throw e_14.error; }
5330
+ }
5331
+ return undefined;
5332
+ }
5333
+ try {
5334
+ for (var _c = __values(Object.keys(match)), _d = _c.next(); !_d.done; _d = _c.next()) {
5335
+ var key = _d.value;
5336
+ var value = match[key];
5337
+ if (key.startsWith('$')) {
5338
+ var found = findMatchConditionForField(value, targetField, prefix);
5339
+ if (found !== undefined) {
5340
+ return found;
5341
+ }
5342
+ continue;
5343
+ }
5344
+ var currentPath = prefix ? "".concat(prefix, ".").concat(key) : key;
5345
+ if (currentPath === targetField) {
5346
+ return value;
5347
+ }
5348
+ if (value && typeof value === 'object') {
5349
+ var found = findMatchConditionForField(value, targetField, currentPath);
5350
+ if (found !== undefined) {
5351
+ return found;
5352
+ }
5353
+ }
5354
+ }
5355
+ }
5356
+ catch (e_15_1) { e_15 = { error: e_15_1 }; }
5357
+ finally {
5358
+ try {
5359
+ if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
5360
+ }
5361
+ finally { if (e_15) throw e_15.error; }
5362
+ }
5363
+ return undefined;
5364
+ }
5365
+ function stripMatchFields(match, fields) {
5366
+ var result = match;
5367
+ fields.forEach(function (field) {
5368
+ result = stripMatchField(result, field);
5369
+ });
5370
+ return result;
5371
+ }
5372
+ function isDateCondition(value) {
5373
+ if (!value) {
5374
+ return false;
5375
+ }
5376
+ if (value instanceof Date) {
5377
+ return true;
5378
+ }
5379
+ if (typeof value === 'object' && !Array.isArray(value)) {
5380
+ return hasDateRangeOperators(value);
5381
+ }
5382
+ return false;
5383
+ }
5384
+ function isChemicalFieldPath(field) {
5385
+ var normalized = normalizeOptionalString(field).toLowerCase();
5386
+ return normalized.includes('chemical');
5387
+ }
5388
+ function detectIdLikeValue(value) {
5389
+ if (!value) {
5390
+ return false;
5391
+ }
5392
+ if (isMongoObjectId(value)) {
5393
+ return true;
5394
+ }
5395
+ if (typeof value === 'string' && isObjectIdString(value)) {
5396
+ return true;
5397
+ }
5398
+ if (isPlainObject(value)) {
5399
+ return true;
5400
+ }
5401
+ return false;
5402
+ }
5403
+ function detectChemicalIdFromProbe(probeDocs, fields) {
5404
+ var e_16, _a, e_17, _b;
5405
+ if (!Array.isArray(probeDocs) || !probeDocs.length) {
5406
+ return false;
5407
+ }
5408
+ var targets = fields.filter(function (field) { return isChemicalFieldPath(field); });
5409
+ if (!targets.length) {
5410
+ return false;
5411
+ }
5412
+ try {
5413
+ for (var probeDocs_1 = __values(probeDocs), probeDocs_1_1 = probeDocs_1.next(); !probeDocs_1_1.done; probeDocs_1_1 = probeDocs_1.next()) {
5414
+ var doc = probeDocs_1_1.value;
5415
+ try {
5416
+ for (var targets_1 = (e_17 = void 0, __values(targets)), targets_1_1 = targets_1.next(); !targets_1_1.done; targets_1_1 = targets_1.next()) {
5417
+ var field = targets_1_1.value;
5418
+ var value = getValueAtPath(doc, field);
5419
+ if (Array.isArray(value)) {
5420
+ if (value.some(function (entry) { return detectIdLikeValue(entry); })) {
5421
+ return true;
5422
+ }
5423
+ }
5424
+ else if (detectIdLikeValue(value)) {
5425
+ return true;
5426
+ }
5427
+ }
5428
+ }
5429
+ catch (e_17_1) { e_17 = { error: e_17_1 }; }
5430
+ finally {
5431
+ try {
5432
+ if (targets_1_1 && !targets_1_1.done && (_b = targets_1.return)) _b.call(targets_1);
5433
+ }
5434
+ finally { if (e_17) throw e_17.error; }
5435
+ }
5436
+ }
5437
+ }
5438
+ catch (e_16_1) { e_16 = { error: e_16_1 }; }
5439
+ finally {
5440
+ try {
5441
+ if (probeDocs_1_1 && !probeDocs_1_1.done && (_a = probeDocs_1.return)) _a.call(probeDocs_1);
5442
+ }
5443
+ finally { if (e_16) throw e_16.error; }
5444
+ }
5445
+ return false;
5446
+ }
5447
+ function isEmptyQueryValue(value) {
5448
+ if (value === null || value === undefined) {
5449
+ return true;
5450
+ }
5451
+ if (Array.isArray(value)) {
5452
+ return value.length === 0;
5453
+ }
5454
+ if (typeof value === 'object') {
5455
+ return Object.keys(value).length === 0;
5456
+ }
5457
+ return false;
5458
+ }
5459
+ function stripQueryFieldPathsDeepWithMeta(query, fieldsToStrip) {
5460
+ var fieldSet = new Set((fieldsToStrip || []).filter(Boolean));
5461
+ var stripValue = function (value, prefix) {
5462
+ if (Array.isArray(value)) {
5463
+ var changed_1 = false;
5464
+ var nextArray = value
5465
+ .map(function (entry) {
5466
+ var stripped = stripValue(entry, prefix);
5467
+ if (stripped.changed) {
5468
+ changed_1 = true;
5469
+ }
5470
+ return stripped.value;
5471
+ })
5472
+ .filter(function (entry) { return !isEmptyQueryValue(entry); });
5473
+ if (nextArray.length !== value.length) {
5474
+ changed_1 = true;
5475
+ }
5476
+ return { value: nextArray, changed: changed_1 };
5477
+ }
5478
+ if (!value || typeof value !== 'object' || value instanceof Date || value instanceof RegExp || isMongoObjectId(value)) {
5479
+ return { value: value, changed: false };
5480
+ }
5481
+ var result = {};
5482
+ var changed = false;
5483
+ var keys = Object.keys(value);
5484
+ keys.forEach(function (key) {
5485
+ var entry = value[key];
5486
+ if (key.startsWith('$')) {
5487
+ if (Array.isArray(entry) && (key === '$and' || key === '$or' || key === '$nor')) {
5488
+ var stripped = stripValue(entry, prefix);
5489
+ var arrayValue = Array.isArray(stripped.value) ? stripped.value : [];
5490
+ if (arrayValue.length === 0) {
5491
+ changed = true;
5492
+ return;
5493
+ }
5494
+ if (arrayValue.length !== entry.length || stripped.changed) {
5495
+ changed = true;
5496
+ }
5497
+ result[key] = arrayValue;
5498
+ return;
5499
+ }
5500
+ if (entry && typeof entry === 'object') {
5501
+ var stripped = stripValue(entry, prefix);
5502
+ if (stripped.changed) {
5503
+ changed = true;
5504
+ }
5505
+ result[key] = stripped.value;
5506
+ return;
5507
+ }
5508
+ result[key] = entry;
5509
+ return;
5510
+ }
5511
+ var currentPath = prefix ? "".concat(prefix, ".").concat(key) : key;
5512
+ if (fieldSet.has(currentPath)) {
5513
+ changed = true;
5514
+ return;
5515
+ }
5516
+ if (entry && typeof entry === 'object') {
5517
+ var stripped = stripValue(entry, currentPath);
5518
+ if (stripped.changed) {
5519
+ changed = true;
5520
+ }
5521
+ if (!isEmptyQueryValue(stripped.value)) {
5522
+ result[key] = stripped.value;
5523
+ }
5524
+ else {
5525
+ changed = true;
5526
+ }
5527
+ return;
5528
+ }
5529
+ result[key] = entry;
5530
+ });
5531
+ var resultKeys = Object.keys(result);
5532
+ if (resultKeys.length === 1 && (resultKeys[0] === '$and' || resultKeys[0] === '$or')) {
5533
+ var only = result[resultKeys[0]];
5534
+ if (Array.isArray(only) && only.length === 1) {
5535
+ return { value: only[0], changed: true };
5536
+ }
5537
+ }
5538
+ return { value: result, changed: changed };
5539
+ };
5540
+ return stripValue(query, '');
5541
+ }
5542
+ function stripQueryFieldPathsDeep(query, fieldsToStrip) {
5543
+ return stripQueryFieldPathsDeepWithMeta(query, fieldsToStrip).value;
5544
+ }
5545
+ function stripScopedFieldsFromPipelineWithMeta(pipeline, fieldsToStrip) {
5546
+ if (!Array.isArray(pipeline)) {
5547
+ return { pipeline: [], changed: false };
5548
+ }
5549
+ var changed = false;
5550
+ var nextPipeline = pipeline.map(function (stage) {
5551
+ if (!stage || typeof stage !== 'object') {
5552
+ return stage;
5553
+ }
5554
+ var nextStage = stage;
5555
+ if (stage.$match && typeof stage.$match === 'object') {
5556
+ var stripped = stripQueryFieldPathsDeepWithMeta(stage.$match, fieldsToStrip);
5557
+ if (stripped.changed) {
5558
+ changed = true;
5559
+ }
5560
+ nextStage = __assign(__assign({}, nextStage), { $match: stripped.value });
5561
+ }
5562
+ if (stage.$geoNear && typeof stage.$geoNear === 'object' && stage.$geoNear.query) {
5563
+ var stripped = stripQueryFieldPathsDeepWithMeta(stage.$geoNear.query, fieldsToStrip);
5564
+ if (stripped.changed) {
5565
+ changed = true;
5566
+ }
5567
+ nextStage = __assign(__assign({}, nextStage), { $geoNear: __assign(__assign({}, stage.$geoNear), { query: stripped.value }) });
5568
+ }
5569
+ return nextStage;
5570
+ });
5571
+ return { pipeline: nextPipeline, changed: changed };
5572
+ }
5573
+ function stripScopedFieldsFromPipeline(pipeline, fieldsToStrip) {
5574
+ return stripScopedFieldsFromPipelineWithMeta(pipeline, fieldsToStrip).pipeline;
5575
+ }
5576
+ function isIdLookupCondition(value) {
5577
+ if (!value) {
5578
+ return false;
5579
+ }
5580
+ if (value instanceof RegExp) {
5581
+ return true;
5582
+ }
5583
+ if (typeof value === 'string') {
5584
+ return !isObjectIdString(value.trim());
5585
+ }
5586
+ if (typeof value === 'object') {
5587
+ return Object.prototype.hasOwnProperty.call(value, '$regex');
5588
+ }
5589
+ return false;
5590
+ }
5591
+ function collectIdFieldConditions(match) {
5592
+ var results = [];
5593
+ var visit = function (value) {
5594
+ if (Array.isArray(value)) {
5595
+ value.forEach(function (entry) { return visit(entry); });
5596
+ return;
5597
+ }
5598
+ if (!value || typeof value !== 'object') {
5599
+ return;
5600
+ }
5601
+ Object.keys(value).forEach(function (key) {
5602
+ var entry = value[key];
5603
+ if (key.startsWith('$')) {
5604
+ visit(entry);
5605
+ return;
5606
+ }
5607
+ if (isAssistantIdField(key) && isIdLookupCondition(entry)) {
5608
+ results.push({ field: key, condition: entry });
5609
+ return;
5610
+ }
5611
+ if (entry && typeof entry === 'object') {
5612
+ visit(entry);
5613
+ }
5614
+ });
5615
+ };
5616
+ visit(match);
5617
+ return results;
5618
+ }
5619
+ function resolveLocalNameFieldFromDocs(docs, baseToken) {
5620
+ var normalizedBase = normalizeOptionalString(baseToken);
5621
+ if (!normalizedBase || !Array.isArray(docs) || !docs.length) {
5622
+ return null;
5623
+ }
5624
+ if (hasNonEmptyValue(docs, normalizedBase, { treatObjectLikeAsEmpty: true })) {
5625
+ return normalizedBase;
5626
+ }
5627
+ var aliases = resolveFieldAliases(docs, [normalizedBase]);
5628
+ return aliases[normalizedBase] || null;
5629
+ }
5630
+ function buildIdFieldNameFallbackQuery(query, idField, nameField, condition) {
5631
+ var _a, _b;
5632
+ var baseMatch = stripMatchField(query, idField);
5633
+ var orConditions = [
5634
+ (_a = {}, _a[idField] = condition, _a),
5635
+ (_b = {}, _b[nameField] = condition, _b)
5636
+ ];
5637
+ var nextMatch = isEmptyMatchValue(baseMatch)
5638
+ ? { $or: orConditions }
5639
+ : { $and: [baseMatch, { $or: orConditions }] };
5640
+ return nextMatch;
5641
+ }
5642
+ function buildChemicalIdFieldCandidates(field) {
5643
+ var normalized = normalizeOptionalString(field);
5644
+ if (!normalized) {
5645
+ return [];
5646
+ }
5647
+ var parts = normalized.split('.').filter(Boolean);
5648
+ var leaf = parts[parts.length - 1] || normalized;
5649
+ var prefix = parts.length > 1 ? parts.slice(0, -1).join('.') : '';
5650
+ var withPrefix = function (value) { return (prefix ? "".concat(prefix, ".").concat(value) : value); };
5651
+ var candidates = new Set();
5652
+ candidates.add(normalized);
5653
+ if (!leaf.startsWith('id_')) {
5654
+ candidates.add(withPrefix('id_chemical'));
5655
+ candidates.add(withPrefix('chemical_id'));
5656
+ candidates.add(withPrefix('chemicalId'));
5657
+ candidates.add(withPrefix('idChemical'));
5658
+ }
5659
+ return Array.from(candidates);
5660
+ }
5661
+ function applyChemicalNameLookupFallbackToQuery(params) {
5662
+ return __awaiter(this, void 0, void 0, function () {
5663
+ var query, db, dbName, idClient, idCustomer, isSuperAdmin, probeDocs, chemicalFields, targetField, condition, regex, sampleDocs, collectionNames, candidates, _loop_6, candidates_2, candidates_2_1, candidate, state_4, e_18_1;
5664
+ var e_18, _a;
5665
+ var _b;
5666
+ return __generator(this, function (_c) {
5667
+ switch (_c.label) {
5668
+ case 0:
5669
+ query = params.query, db = params.db, dbName = params.dbName, idClient = params.idClient, idCustomer = params.idCustomer, isSuperAdmin = params.isSuperAdmin, probeDocs = params.probeDocs;
5670
+ chemicalFields = collectMatchFieldsByCondition(query, function (field, condition) { return (isRegexMatchCondition(condition) && isChemicalFieldPath(field)); });
5671
+ if (!chemicalFields.length) {
5672
+ return [2 /*return*/, null];
5673
+ }
5674
+ targetField = chemicalFields[0];
5675
+ condition = findMatchConditionForField(query, targetField);
5676
+ regex = buildRegexFromCondition(condition);
5677
+ if (!regex) {
5678
+ return [2 /*return*/, null];
5679
+ }
5680
+ sampleDocs = Array.isArray(probeDocs) ? probeDocs : [];
5681
+ if (!detectChemicalIdFromProbe(sampleDocs, [targetField])) {
5682
+ return [2 /*return*/, null];
5683
+ }
5684
+ return [4 /*yield*/, listAssistantCollections(db, dbName)];
5685
+ case 1:
5686
+ collectionNames = _c.sent();
5687
+ candidates = resolveIdLookupCandidates('chemical', collectionNames);
5688
+ _loop_6 = function (candidate) {
5689
+ var candidateHasClientScope, _d, candidateProbe, lookup, idFields, baseMatch, orConditions, nextMatch;
5690
+ return __generator(this, function (_e) {
5691
+ switch (_e.label) {
5692
+ case 0:
5693
+ if (!candidate) {
5694
+ return [2 /*return*/, "continue"];
5695
+ }
5696
+ if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(candidate)) {
5697
+ return [2 /*return*/, "continue"];
5698
+ }
5699
+ if (!idClient) return [3 /*break*/, 2];
5700
+ return [4 /*yield*/, collectionHasClientIndex(db, dbName, candidate)];
5701
+ case 1:
5702
+ _d = _e.sent();
5703
+ return [3 /*break*/, 3];
5704
+ case 2:
5705
+ _d = false;
5706
+ _e.label = 3;
5707
+ case 3:
5708
+ candidateHasClientScope = _d;
5709
+ return [4 /*yield*/, fetchAssistantProbeDocs({
5710
+ db: db,
5711
+ collection: candidate,
5712
+ idClient: idClient,
5713
+ idCustomer: idCustomer,
5714
+ isSuperAdmin: isSuperAdmin,
5715
+ includeClientScope: candidateHasClientScope
5716
+ })];
5717
+ case 4:
5718
+ candidateProbe = _e.sent();
5719
+ return [4 /*yield*/, lookupIdsForNameMatch({
5720
+ db: db,
5721
+ dbName: dbName,
5722
+ collection: candidate,
5723
+ baseToken: 'chemical',
5724
+ regex: regex,
5725
+ idClient: idClient,
5726
+ idCustomer: idCustomer,
5727
+ isSuperAdmin: isSuperAdmin,
5728
+ probeDocs: candidateProbe
5729
+ })];
5730
+ case 5:
5731
+ lookup = _e.sent();
5732
+ if ((_b = lookup === null || lookup === void 0 ? void 0 : lookup.ids) === null || _b === void 0 ? void 0 : _b.length) {
5733
+ idFields = buildChemicalIdFieldCandidates(targetField);
5734
+ baseMatch = stripMatchField(query, targetField);
5735
+ orConditions = idFields.map(function (field) {
5736
+ var _a;
5737
+ return (_a = {}, _a[field] = { $in: lookup.ids }, _a);
5738
+ });
5739
+ nextMatch = isEmptyMatchValue(baseMatch)
5740
+ ? { $or: orConditions }
5741
+ : { $and: [baseMatch, { $or: orConditions }] };
5742
+ return [2 /*return*/, { value: {
5743
+ query: nextMatch,
5744
+ meta: {
5745
+ field: targetField,
5746
+ strategy: 'chemical_lookup',
5747
+ collection: candidate,
5748
+ ids: lookup.ids.length,
5749
+ fields: lookup.fields,
5750
+ idFields: idFields
5751
+ }
5752
+ } }];
5753
+ }
5754
+ return [2 /*return*/];
5755
+ }
5756
+ });
5757
+ };
5758
+ _c.label = 2;
5759
+ case 2:
5760
+ _c.trys.push([2, 7, 8, 9]);
5761
+ candidates_2 = __values(candidates), candidates_2_1 = candidates_2.next();
5762
+ _c.label = 3;
5763
+ case 3:
5764
+ if (!!candidates_2_1.done) return [3 /*break*/, 6];
5765
+ candidate = candidates_2_1.value;
5766
+ return [5 /*yield**/, _loop_6(candidate)];
5767
+ case 4:
5768
+ state_4 = _c.sent();
5769
+ if (typeof state_4 === "object")
5770
+ return [2 /*return*/, state_4.value];
5771
+ _c.label = 5;
5772
+ case 5:
5773
+ candidates_2_1 = candidates_2.next();
5774
+ return [3 /*break*/, 3];
5775
+ case 6: return [3 /*break*/, 9];
5776
+ case 7:
5777
+ e_18_1 = _c.sent();
5778
+ e_18 = { error: e_18_1 };
5779
+ return [3 /*break*/, 9];
5780
+ case 8:
5781
+ try {
5782
+ if (candidates_2_1 && !candidates_2_1.done && (_a = candidates_2.return)) _a.call(candidates_2);
5783
+ }
5784
+ finally { if (e_18) throw e_18.error; }
5785
+ return [7 /*endfinally*/];
5786
+ case 9: return [2 /*return*/, null];
5787
+ }
5788
+ });
5789
+ });
5790
+ }
5791
+ function resolveIdLookupCandidates(baseToken, collectionNames) {
5792
+ var normalizedBase = normalizeOptionalString(baseToken).toLowerCase();
5793
+ if (!normalizedBase || !Array.isArray(collectionNames) || !collectionNames.length) {
5794
+ return [];
5795
+ }
5796
+ var candidates = new Set();
5797
+ var hints = AI_ASSISTANT_ID_LOOKUP_HINTS[normalizedBase] || [];
5798
+ hints.forEach(function (hint) {
5799
+ if (collectionNames.includes(hint)) {
5800
+ candidates.add(hint);
5801
+ }
5802
+ });
5803
+ var tokens = tokenizeCollectionText(normalizedBase);
5804
+ var ranked = collectionNames
5805
+ .map(function (name) { return ({ name: name, score: scoreCollectionMatch(tokens, name) }); })
5806
+ .filter(function (entry) { return entry.score > 0; })
5807
+ .sort(function (a, b) { return b.score - a.score; })
5808
+ .slice(0, AI_ASSISTANT_ID_LOOKUP_CANDIDATE_LIMIT);
5809
+ ranked.forEach(function (entry) { return candidates.add(entry.name); });
5810
+ return Array.from(candidates);
5811
+ }
5812
+ function buildNameLookupFields(baseToken, docs) {
5813
+ var normalizedBase = normalizeOptionalString(baseToken);
5814
+ var candidates = expandNameFieldCandidates(normalizedBase);
5815
+ if (!Array.isArray(docs) || !docs.length) {
5816
+ return candidates;
5817
+ }
5818
+ var available = collectFieldCandidates(docs);
5819
+ var filtered = candidates.filter(function (field) {
5820
+ var stats = available.get(field);
5821
+ return !!stats && stats.nonEmpty > 0;
5822
+ });
5823
+ return filtered.length ? filtered : candidates;
5824
+ }
5825
+ function lookupIdsForNameMatch(params) {
5826
+ return __awaiter(this, void 0, void 0, function () {
5827
+ var db, dbName, collection, baseToken, regex, idClient, idCustomer, isSuperAdmin, probeDocs, fields, query, hasClient, normalizedCustomer, hasCustomer, projection, docs, ids;
5828
+ return __generator(this, function (_a) {
5829
+ switch (_a.label) {
5830
+ case 0:
5831
+ db = params.db, dbName = params.dbName, collection = params.collection, baseToken = params.baseToken, regex = params.regex, idClient = params.idClient, idCustomer = params.idCustomer, isSuperAdmin = params.isSuperAdmin, probeDocs = params.probeDocs;
5832
+ fields = buildNameLookupFields(baseToken, probeDocs);
5833
+ if (!fields.length) {
5834
+ return [2 /*return*/, null];
5835
+ }
5836
+ query = { $or: fields.map(function (field) {
5837
+ var _a;
5838
+ return (_a = {}, _a[field] = regex, _a);
5839
+ }) };
5840
+ if (!!isSuperAdmin) return [3 /*break*/, 3];
5841
+ return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
5842
+ case 1:
5843
+ hasClient = _a.sent();
5844
+ if (hasClient) {
5845
+ query = applyClientScopeFilter(query, idClient, isSuperAdmin);
5846
+ }
5847
+ normalizedCustomer = normalizeOptionalString(idCustomer);
5848
+ if (!(normalizedCustomer && collection !== 'customers')) return [3 /*break*/, 3];
5849
+ return [4 /*yield*/, collectionHasFieldIndex(db, dbName, collection, 'id_customer')];
5850
+ case 2:
5851
+ hasCustomer = _a.sent();
5852
+ if (hasCustomer) {
5853
+ query = applyCustomerScopeFilter(query, collection, normalizedCustomer, isSuperAdmin);
5854
+ }
5855
+ _a.label = 3;
5856
+ case 3:
5857
+ projection = { _id: 1 };
5858
+ fields.forEach(function (field) {
5859
+ projection[field] = 1;
5860
+ });
5861
+ return [4 /*yield*/, db.collection(collection)
5862
+ .find(query, {
5863
+ projection: projection,
5864
+ limit: AI_ASSISTANT_ID_LOOKUP_MAX_RESULTS,
5865
+ readPreference: AI_ASSISTANT_READ_PREFERENCE
5866
+ })
5867
+ .toArray()];
5868
+ case 4:
5869
+ docs = _a.sent();
5870
+ ids = docs.map(function (doc) { return doc === null || doc === void 0 ? void 0 : doc._id; }).filter(Boolean);
5871
+ return [2 /*return*/, ids.length ? { ids: ids, fields: fields } : null];
5872
+ }
5873
+ });
5874
+ });
5875
+ }
5876
+ function applyIdLookupFallbackToQuery(params) {
5877
+ return __awaiter(this, void 0, void 0, function () {
5878
+ var query, db, dbName, idClient, idCustomer, isSuperAdmin, probeDocs, conditions, collectionNames, _a, conditions_1, conditions_1_1, condition, regex, baseToken, targetFieldType, nextValue, localNameField, candidates, candidates_3, candidates_3_1, candidate, candidateHasClientScope, _b, candidateProbe, lookup, targetFieldType, normalizedIds, idsForQuery, e_19_1, e_20_1;
5879
+ var e_20, _c, e_19, _d;
5880
+ var _e;
5881
+ return __generator(this, function (_f) {
5882
+ switch (_f.label) {
5883
+ case 0:
5884
+ query = params.query, db = params.db, dbName = params.dbName, idClient = params.idClient, idCustomer = params.idCustomer, isSuperAdmin = params.isSuperAdmin, probeDocs = params.probeDocs;
5885
+ conditions = collectIdFieldConditions(query);
5886
+ if (!conditions.length) {
5887
+ return [2 /*return*/, null];
5888
+ }
5889
+ _a = params.collectionNames;
5890
+ if (_a) return [3 /*break*/, 2];
5891
+ return [4 /*yield*/, listAssistantCollections(db, dbName)];
5892
+ case 1:
5893
+ _a = (_f.sent());
5894
+ _f.label = 2;
5895
+ case 2:
5896
+ collectionNames = _a;
5897
+ _f.label = 3;
5898
+ case 3:
5899
+ _f.trys.push([3, 18, 19, 20]);
5900
+ conditions_1 = __values(conditions), conditions_1_1 = conditions_1.next();
5901
+ _f.label = 4;
5902
+ case 4:
5903
+ if (!!conditions_1_1.done) return [3 /*break*/, 17];
5904
+ condition = conditions_1_1.value;
5905
+ regex = buildRegexFromCondition(condition.condition);
5906
+ if (!regex) {
5907
+ return [3 /*break*/, 16];
5908
+ }
5909
+ baseToken = normalizeIdFieldBase(condition.field);
5910
+ if (!baseToken) {
5911
+ return [3 /*break*/, 16];
5912
+ }
5913
+ if (baseToken === 'customer' && idCustomer) {
5914
+ targetFieldType = inferIdFieldStorageTypeFromDocs(probeDocs || [], condition.field);
5915
+ nextValue = idCustomer;
5916
+ if (targetFieldType === 'objectId' && isObjectIdString(idCustomer)) {
5917
+ try {
5918
+ nextValue = new mongodb_1.ObjectId(idCustomer);
5919
+ }
5920
+ catch (_g) {
5921
+ nextValue = idCustomer;
5922
+ }
5923
+ }
5924
+ return [2 /*return*/, {
5925
+ query: replaceQueryFieldCondition(query, condition.field, nextValue),
5926
+ meta: {
5927
+ field: condition.field,
5928
+ strategy: 'customer_scope',
5929
+ value: idCustomer,
5930
+ targetFieldType: targetFieldType
5931
+ }
5932
+ }];
5933
+ }
5934
+ localNameField = resolveLocalNameFieldFromDocs(probeDocs || [], baseToken);
5935
+ if (localNameField) {
5936
+ return [2 /*return*/, {
5937
+ query: buildIdFieldNameFallbackQuery(query, condition.field, localNameField, regex),
5938
+ meta: {
5939
+ field: condition.field,
5940
+ strategy: 'local_name',
5941
+ nameField: localNameField
5942
+ }
5943
+ }];
5944
+ }
5945
+ candidates = resolveIdLookupCandidates(baseToken, collectionNames);
5946
+ _f.label = 5;
5947
+ case 5:
5948
+ _f.trys.push([5, 14, 15, 16]);
5949
+ candidates_3 = (e_19 = void 0, __values(candidates)), candidates_3_1 = candidates_3.next();
5950
+ _f.label = 6;
5951
+ case 6:
5952
+ if (!!candidates_3_1.done) return [3 /*break*/, 13];
5953
+ candidate = candidates_3_1.value;
5954
+ if (!candidate) {
5955
+ return [3 /*break*/, 12];
5956
+ }
5957
+ if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(candidate)) {
5958
+ return [3 /*break*/, 12];
5959
+ }
5960
+ if (!idClient) return [3 /*break*/, 8];
5961
+ return [4 /*yield*/, collectionHasClientIndex(db, dbName, candidate)];
5962
+ case 7:
5963
+ _b = _f.sent();
5964
+ return [3 /*break*/, 9];
5965
+ case 8:
5966
+ _b = false;
5967
+ _f.label = 9;
5968
+ case 9:
5969
+ candidateHasClientScope = _b;
5970
+ return [4 /*yield*/, fetchAssistantProbeDocs({
5971
+ db: db,
5972
+ collection: candidate,
5973
+ idClient: idClient,
5974
+ idCustomer: idCustomer,
5975
+ isSuperAdmin: isSuperAdmin,
5976
+ includeClientScope: candidateHasClientScope
5977
+ })];
5978
+ case 10:
5979
+ candidateProbe = _f.sent();
5980
+ return [4 /*yield*/, lookupIdsForNameMatch({
5981
+ db: db,
5982
+ dbName: dbName,
5983
+ collection: candidate,
5984
+ baseToken: baseToken,
5985
+ regex: regex,
5986
+ idClient: idClient,
5987
+ idCustomer: idCustomer,
5988
+ isSuperAdmin: isSuperAdmin,
5989
+ probeDocs: candidateProbe
5990
+ })];
5991
+ case 11:
5992
+ lookup = _f.sent();
5993
+ if ((_e = lookup === null || lookup === void 0 ? void 0 : lookup.ids) === null || _e === void 0 ? void 0 : _e.length) {
5994
+ targetFieldType = inferIdFieldStorageTypeFromDocs(probeDocs || [], condition.field);
5995
+ normalizedIds = normalizeIdsForTargetField(lookup.ids, probeDocs || [], condition.field, targetFieldType);
5996
+ idsForQuery = normalizedIds.length ? normalizedIds : lookup.ids;
5997
+ return [2 /*return*/, {
5998
+ query: replaceQueryFieldCondition(query, condition.field, { $in: idsForQuery }),
5999
+ meta: {
6000
+ field: condition.field,
6001
+ strategy: 'lookup',
6002
+ collection: candidate,
6003
+ ids: lookup.ids.length,
6004
+ idsNormalized: normalizedIds.length,
6005
+ targetFieldType: targetFieldType,
6006
+ fields: lookup.fields
6007
+ }
6008
+ }];
6009
+ }
6010
+ _f.label = 12;
6011
+ case 12:
6012
+ candidates_3_1 = candidates_3.next();
6013
+ return [3 /*break*/, 6];
6014
+ case 13: return [3 /*break*/, 16];
6015
+ case 14:
6016
+ e_19_1 = _f.sent();
6017
+ e_19 = { error: e_19_1 };
6018
+ return [3 /*break*/, 16];
6019
+ case 15:
6020
+ try {
6021
+ if (candidates_3_1 && !candidates_3_1.done && (_d = candidates_3.return)) _d.call(candidates_3);
6022
+ }
6023
+ finally { if (e_19) throw e_19.error; }
6024
+ return [7 /*endfinally*/];
6025
+ case 16:
6026
+ conditions_1_1 = conditions_1.next();
6027
+ return [3 /*break*/, 4];
6028
+ case 17: return [3 /*break*/, 20];
6029
+ case 18:
6030
+ e_20_1 = _f.sent();
6031
+ e_20 = { error: e_20_1 };
6032
+ return [3 /*break*/, 20];
6033
+ case 19:
6034
+ try {
6035
+ if (conditions_1_1 && !conditions_1_1.done && (_c = conditions_1.return)) _c.call(conditions_1);
6036
+ }
6037
+ finally { if (e_20) throw e_20.error; }
6038
+ return [7 /*endfinally*/];
6039
+ case 20: return [2 /*return*/, null];
6040
+ }
6041
+ });
3611
6042
  });
3612
- return result;
3613
6043
  }
3614
6044
  function buildAggregateNameMatchFallbackPipeline(pipeline, fallback) {
3615
6045
  var _a;
@@ -3690,12 +6120,12 @@ function replaceAggregateDateField(pipeline, fromField, toField) {
3690
6120
  return value;
3691
6121
  }
3692
6122
  if (value && typeof value === 'object') {
3693
- var next_1 = {};
6123
+ var next_2 = {};
3694
6124
  Object.keys(value).forEach(function (key) {
3695
6125
  var nextKey = key === fromField ? toField : key;
3696
- next_1[nextKey] = replacer(value[key]);
6126
+ next_2[nextKey] = replacer(value[key]);
3697
6127
  });
3698
- return next_1;
6128
+ return next_2;
3699
6129
  }
3700
6130
  if (typeof value === 'string') {
3701
6131
  if (value.startsWith("$".concat(fromField))) {
@@ -3712,7 +6142,8 @@ function normalizeMongoQuery(query) {
3712
6142
  if (containsForbiddenMongoOperators(normalized)) {
3713
6143
  throw new Error('AI assistant mongo read: Query contains restricted operators.');
3714
6144
  }
3715
- return applyAssistantNameRegexToQuery(normalized);
6145
+ var rewritten = rewriteEmbeddedMatchObjects(normalized);
6146
+ return applyAssistantNameRegexToQuery(rewritten);
3716
6147
  }
3717
6148
  function shouldApplyAssistantNameRegex(field) {
3718
6149
  var normalized = String(field || '').toLowerCase().trim();
@@ -3742,6 +6173,14 @@ function shouldApplyAssistantNameRegex(field) {
3742
6173
  function escapeRegexValue(value) {
3743
6174
  return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
3744
6175
  }
6176
+ function buildTokenizedRegex(value) {
6177
+ var tokens = tokenizeFieldKey(value).filter(function (token) { return token.length; });
6178
+ if (tokens.length <= 1) {
6179
+ return new RegExp(escapeRegexValue(value), 'i');
6180
+ }
6181
+ var tokenPattern = tokens.map(function (token) { return escapeRegexValue(token); }).join('[\\s\\-_]*.*');
6182
+ return new RegExp(tokenPattern, 'i');
6183
+ }
3745
6184
  function applyAssistantNameRegexToQuery(query) {
3746
6185
  if (Array.isArray(query)) {
3747
6186
  return query.map(function (entry) { return applyAssistantNameRegexToQuery(entry); });
@@ -3758,7 +6197,7 @@ function applyAssistantNameRegexToQuery(query) {
3758
6197
  }
3759
6198
  if (typeof value === 'string' && shouldApplyAssistantNameRegex(key)) {
3760
6199
  var trimmed = value.trim();
3761
- result[key] = trimmed ? new RegExp(escapeRegexValue(trimmed), 'i') : value;
6200
+ result[key] = trimmed ? buildTokenizedRegex(trimmed) : value;
3762
6201
  return;
3763
6202
  }
3764
6203
  if (value && typeof value === 'object') {
@@ -3769,6 +6208,127 @@ function applyAssistantNameRegexToQuery(query) {
3769
6208
  });
3770
6209
  return result;
3771
6210
  }
6211
+ function isObjectIdString(value) {
6212
+ return /^[a-f0-9]{24}$/i.test(value);
6213
+ }
6214
+ function isPlainMatchObject(value) {
6215
+ return isPlainObject(value)
6216
+ && !isMongoObjectId(value)
6217
+ && !(value instanceof Date)
6218
+ && !(value instanceof RegExp);
6219
+ }
6220
+ function hasOperatorKeys(value) {
6221
+ if (!value || typeof value !== 'object') {
6222
+ return false;
6223
+ }
6224
+ return Object.keys(value).some(function (key) { return key.startsWith('$'); });
6225
+ }
6226
+ function rewriteEmbeddedMatchObjects(query) {
6227
+ var rewriteValue = function (value, allowArrayRewrite, inOperator) {
6228
+ if (inOperator === void 0) { inOperator = false; }
6229
+ if (Array.isArray(value)) {
6230
+ if (!allowArrayRewrite) {
6231
+ return value;
6232
+ }
6233
+ return value.map(function (entry) { return rewriteValue(entry, true, inOperator); });
6234
+ }
6235
+ if (!value || typeof value !== 'object' || value instanceof Date || value instanceof RegExp || isMongoObjectId(value)) {
6236
+ return value;
6237
+ }
6238
+ var result = {};
6239
+ Object.keys(value).forEach(function (key) {
6240
+ var entry = value[key];
6241
+ if (key.startsWith('$')) {
6242
+ result[key] = rewriteValue(entry, true, true);
6243
+ return;
6244
+ }
6245
+ if (!inOperator && isPlainMatchObject(entry) && !Array.isArray(entry) && !hasOperatorKeys(entry)) {
6246
+ var flattened = flattenMatchObject(entry, key, inOperator);
6247
+ Object.assign(result, flattened);
6248
+ return;
6249
+ }
6250
+ if (isPlainMatchObject(entry) && !Array.isArray(entry)) {
6251
+ result[key] = rewriteValue(entry, true, inOperator);
6252
+ return;
6253
+ }
6254
+ if (Array.isArray(entry)) {
6255
+ result[key] = allowArrayRewrite ? entry.map(function (item) { return rewriteValue(item, true, inOperator); }) : entry;
6256
+ return;
6257
+ }
6258
+ result[key] = entry;
6259
+ });
6260
+ return result;
6261
+ };
6262
+ var flattenMatchObject = function (value, prefix, inOperator) {
6263
+ var result = {};
6264
+ Object.keys(value || {}).forEach(function (key) {
6265
+ var entry = value[key];
6266
+ var currentPath = "".concat(prefix, ".").concat(key);
6267
+ if (isPlainMatchObject(entry) && !Array.isArray(entry) && !hasOperatorKeys(entry)) {
6268
+ var flattened = flattenMatchObject(entry, currentPath, inOperator);
6269
+ Object.assign(result, flattened);
6270
+ return;
6271
+ }
6272
+ if (isPlainMatchObject(entry) && !Array.isArray(entry)) {
6273
+ result[currentPath] = rewriteValue(entry, true, inOperator);
6274
+ return;
6275
+ }
6276
+ if (Array.isArray(entry)) {
6277
+ result[currentPath] = entry;
6278
+ return;
6279
+ }
6280
+ result[currentPath] = entry;
6281
+ });
6282
+ return result;
6283
+ };
6284
+ return rewriteValue(query, true);
6285
+ }
6286
+ function buildRegexFromCondition(condition) {
6287
+ if (!condition) {
6288
+ return null;
6289
+ }
6290
+ if (condition instanceof RegExp) {
6291
+ return condition;
6292
+ }
6293
+ if (typeof condition === 'string') {
6294
+ var trimmed = condition.trim();
6295
+ if (!trimmed || isObjectIdString(trimmed)) {
6296
+ return null;
6297
+ }
6298
+ return new RegExp(escapeRegexValue(trimmed), 'i');
6299
+ }
6300
+ if (typeof condition === 'object') {
6301
+ var raw = condition.$regex;
6302
+ if (raw !== undefined) {
6303
+ var source = String(raw);
6304
+ var options = typeof condition.$options === 'string'
6305
+ ? condition.$options
6306
+ : 'i';
6307
+ try {
6308
+ return new RegExp(source, options);
6309
+ }
6310
+ catch (_a) {
6311
+ return new RegExp(escapeRegexValue(source), 'i');
6312
+ }
6313
+ }
6314
+ }
6315
+ return null;
6316
+ }
6317
+ function normalizeIdFieldBase(field) {
6318
+ var normalized = normalizeOptionalString(field).toLowerCase();
6319
+ if (!normalized) {
6320
+ return '';
6321
+ }
6322
+ var parts = normalized.split('.').filter(Boolean);
6323
+ var last = parts[parts.length - 1] || normalized;
6324
+ if (last.startsWith('id_')) {
6325
+ return last.slice(3);
6326
+ }
6327
+ if (normalized.startsWith('id_')) {
6328
+ return normalized.slice(3);
6329
+ }
6330
+ return last;
6331
+ }
3772
6332
  function normalizeCollectionKey(value) {
3773
6333
  return String(value || '').toLowerCase().replace(/[^a-z0-9]/g, '');
3774
6334
  }
@@ -3803,6 +6363,19 @@ function tokenizeCollectionText(value) {
3803
6363
  });
3804
6364
  return Array.from(new Set(tokens));
3805
6365
  }
6366
+ function computeCollectionTokenWeights(tokens) {
6367
+ var unique = Array.from(new Set(tokens));
6368
+ var hasDomain = unique.some(function (token) { return AI_ASSISTANT_COLLECTION_DOMAIN_TOKENS.has(token); });
6369
+ var weights = {};
6370
+ unique.forEach(function (token) {
6371
+ if (hasDomain && AI_ASSISTANT_COLLECTION_GENERIC_TOKENS.has(token)) {
6372
+ weights[token] = 0.4;
6373
+ return;
6374
+ }
6375
+ weights[token] = 1;
6376
+ });
6377
+ return { weights: weights, hasDomain: hasDomain };
6378
+ }
3806
6379
  function expandAssistantTermSynonyms(text) {
3807
6380
  var base = normalizeOptionalString(text);
3808
6381
  if (!base) {
@@ -3855,7 +6428,7 @@ function listAssistantCollections(db, dbName) {
3855
6428
  });
3856
6429
  });
3857
6430
  }
3858
- function scoreCollectionMatch(requestedTokens, candidateName) {
6431
+ function scoreCollectionMatch(requestedTokens, candidateName, tokenWeights) {
3859
6432
  if (!requestedTokens.length) {
3860
6433
  return 0;
3861
6434
  }
@@ -3865,8 +6438,10 @@ function scoreCollectionMatch(requestedTokens, candidateName) {
3865
6438
  }
3866
6439
  var score = 0;
3867
6440
  requestedTokens.forEach(function (token) {
6441
+ var _a;
3868
6442
  if (candidateTokens.includes(token)) {
3869
- score += 10;
6443
+ var weight = (_a = tokenWeights === null || tokenWeights === void 0 ? void 0 : tokenWeights[token]) !== null && _a !== void 0 ? _a : 1;
6444
+ score += 10 * weight;
3870
6445
  }
3871
6446
  });
3872
6447
  var requestedKey = normalizeCollectionKey(requestedTokens.join('-'));
@@ -3877,12 +6452,17 @@ function scoreCollectionMatch(requestedTokens, candidateName) {
3877
6452
  else if (requestedKey && (candidateKey.includes(requestedKey) || requestedKey.includes(candidateKey))) {
3878
6453
  score += 20;
3879
6454
  }
6455
+ if (isVersionCollectionName(candidateName)) {
6456
+ score -= 15;
6457
+ }
3880
6458
  return score;
3881
6459
  }
3882
- function scoreCollectionMatchDetailed(requestedTokens, candidateName) {
6460
+ function scoreCollectionMatchDetailed(requestedTokens, candidateName, tokenWeights) {
3883
6461
  var candidateTokens = tokenizeCollectionText(candidateName);
3884
6462
  var tokenMatches = requestedTokens.filter(function (token) { return candidateTokens.includes(token); });
3885
- var score = tokenMatches.length * 10;
6463
+ var weights = tokenWeights || {};
6464
+ var tokenScore = tokenMatches.reduce(function (sum, token) { var _a; return sum + 10 * ((_a = weights[token]) !== null && _a !== void 0 ? _a : 1); }, 0);
6465
+ var score = tokenScore;
3886
6466
  var requestedKey = normalizeCollectionKey(requestedTokens.join('-'));
3887
6467
  var candidateKey = normalizeCollectionKey(candidateName);
3888
6468
  var keyMatch = null;
@@ -3894,11 +6474,20 @@ function scoreCollectionMatchDetailed(requestedTokens, candidateName) {
3894
6474
  score += 20;
3895
6475
  keyMatch = 'partial';
3896
6476
  }
6477
+ if (isVersionCollectionName(candidateName)) {
6478
+ score -= 15;
6479
+ }
3897
6480
  return {
3898
6481
  score: score,
3899
6482
  tokenMatches: tokenMatches,
3900
6483
  keyMatch: keyMatch,
3901
- candidateTokens: candidateTokens
6484
+ candidateTokens: candidateTokens,
6485
+ tokenScore: tokenScore,
6486
+ tokenWeights: tokenMatches.reduce(function (acc, token) {
6487
+ var _a;
6488
+ acc[token] = (_a = weights[token]) !== null && _a !== void 0 ? _a : 1;
6489
+ return acc;
6490
+ }, {})
3902
6491
  };
3903
6492
  }
3904
6493
  function resolveCollectionHintsFromTokens(tokens, collectionNames, max) {
@@ -3906,8 +6495,9 @@ function resolveCollectionHintsFromTokens(tokens, collectionNames, max) {
3906
6495
  if (!tokens.length || !collectionNames.length) {
3907
6496
  return [];
3908
6497
  }
6498
+ var weights = computeCollectionTokenWeights(tokens).weights;
3909
6499
  return collectionNames
3910
- .map(function (name) { return ({ name: name, score: scoreCollectionMatch(tokens, name) }); })
6500
+ .map(function (name) { return ({ name: name, score: scoreCollectionMatch(tokens, name, weights) }); })
3911
6501
  .filter(function (entry) { return entry.score > 0; })
3912
6502
  .sort(function (a, b) { return b.score - a.score; })
3913
6503
  .slice(0, Math.max(max, 0))
@@ -3916,21 +6506,26 @@ function resolveCollectionHintsFromTokens(tokens, collectionNames, max) {
3916
6506
  function buildCollectionRankingDebugFromTokens(tokens, collectionNames, max) {
3917
6507
  if (max === void 0) { max = 8; }
3918
6508
  var requestedKey = normalizeCollectionKey(tokens.join('-'));
6509
+ var _a = computeCollectionTokenWeights(tokens), weights = _a.weights, hasDomain = _a.hasDomain;
3919
6510
  if (!tokens.length || !collectionNames.length) {
3920
6511
  return {
3921
6512
  tokens: tokens,
3922
6513
  requestedKey: requestedKey,
6514
+ hasDomain: hasDomain,
6515
+ tokenWeights: weights,
3923
6516
  ranked: []
3924
6517
  };
3925
6518
  }
3926
6519
  var ranked = collectionNames
3927
- .map(function (name) { return (__assign({ name: name }, scoreCollectionMatchDetailed(tokens, name))); })
6520
+ .map(function (name) { return (__assign({ name: name }, scoreCollectionMatchDetailed(tokens, name, weights))); })
3928
6521
  .filter(function (entry) { return entry.score > 0; })
3929
6522
  .sort(function (a, b) { return b.score - a.score; })
3930
6523
  .slice(0, Math.max(max, 0));
3931
6524
  return {
3932
6525
  tokens: tokens,
3933
6526
  requestedKey: requestedKey,
6527
+ hasDomain: hasDomain,
6528
+ tokenWeights: weights,
3934
6529
  ranked: ranked
3935
6530
  };
3936
6531
  }
@@ -3939,13 +6534,187 @@ function buildCollectionSelectionDetail(tokens, collection) {
3939
6534
  if (!trimmed) {
3940
6535
  return null;
3941
6536
  }
3942
- var detail = scoreCollectionMatchDetailed(tokens, trimmed);
6537
+ var weights = computeCollectionTokenWeights(tokens).weights;
6538
+ var detail = scoreCollectionMatchDetailed(tokens, trimmed, weights);
3943
6539
  return {
3944
6540
  collection: trimmed,
3945
6541
  score: detail.score,
3946
6542
  tokenMatches: detail.tokenMatches,
3947
6543
  keyMatch: detail.keyMatch,
3948
- candidateTokens: detail.candidateTokens
6544
+ candidateTokens: detail.candidateTokens,
6545
+ tokenScore: detail.tokenScore,
6546
+ tokenWeights: detail.tokenWeights
6547
+ };
6548
+ }
6549
+ function isVersionCollectionName(value) {
6550
+ var normalized = normalizeOptionalString(value).toLowerCase();
6551
+ return normalized.endsWith('.versions') || normalized.endsWith('-versions') || normalized.includes('.versions.');
6552
+ }
6553
+ function stripVersionSuffix(value) {
6554
+ var normalized = normalizeOptionalString(value);
6555
+ if (!normalized) {
6556
+ return '';
6557
+ }
6558
+ if (normalized.endsWith('.versions')) {
6559
+ return normalized.slice(0, -'.versions'.length);
6560
+ }
6561
+ if (normalized.endsWith('-versions')) {
6562
+ return normalized.slice(0, -'-versions'.length);
6563
+ }
6564
+ return normalized;
6565
+ }
6566
+ function shouldAllowVersionCollections(message) {
6567
+ var normalized = normalizeOptionalString(message).toLowerCase();
6568
+ if (!normalized) {
6569
+ return false;
6570
+ }
6571
+ if (!normalized.includes('bug')) {
6572
+ return false;
6573
+ }
6574
+ return /(last\s*(5|five)\s+updates|version|history|audit)/i.test(normalized);
6575
+ }
6576
+ function resolveReportCollectionName(permissionView, collectionNames, currentCollection) {
6577
+ var normalizedView = normalizeOptionalString(permissionView).toLowerCase();
6578
+ if (!normalizedView.startsWith('/report/')) {
6579
+ return null;
6580
+ }
6581
+ var current = stripVersionSuffix(normalizeOptionalString(currentCollection));
6582
+ var reportCollection = current.startsWith('report-') ? current : "report-".concat(current);
6583
+ if (collectionNames.includes(reportCollection)) {
6584
+ return reportCollection;
6585
+ }
6586
+ var routeTail = normalizedView.replace('/report/', '').replace(/\//g, '-');
6587
+ var routeCandidate = routeTail ? "report-".concat(routeTail) : '';
6588
+ if (routeCandidate && collectionNames.includes(routeCandidate)) {
6589
+ return routeCandidate;
6590
+ }
6591
+ return null;
6592
+ }
6593
+ function resolveBaseCollectionFromReport(db, dbName, collection) {
6594
+ return __awaiter(this, void 0, void 0, function () {
6595
+ var normalized, base, names;
6596
+ return __generator(this, function (_a) {
6597
+ switch (_a.label) {
6598
+ case 0:
6599
+ normalized = normalizeOptionalString(collection);
6600
+ if (!normalized.startsWith('report-')) {
6601
+ return [2 /*return*/, null];
6602
+ }
6603
+ base = stripVersionSuffix(normalized.slice('report-'.length));
6604
+ if (!base) {
6605
+ return [2 /*return*/, null];
6606
+ }
6607
+ return [4 /*yield*/, listAssistantCollections(db, dbName)];
6608
+ case 1:
6609
+ names = _a.sent();
6610
+ return [2 /*return*/, names.includes(base) ? base : null];
6611
+ }
6612
+ });
6613
+ });
6614
+ }
6615
+ function resolveCollectionOverrideWithContext(params) {
6616
+ var requested = normalizeOptionalString(params.requestedCollection);
6617
+ var allowVersions = shouldAllowVersionCollections(params.message);
6618
+ var collectionNames = Array.isArray(params.collectionNames) ? params.collectionNames : [];
6619
+ var permissionView = normalizeOptionalString(params.permissionView);
6620
+ if (permissionView) {
6621
+ var reportPreferred = resolveReportCollectionName(permissionView, collectionNames, requested);
6622
+ if (reportPreferred && reportPreferred !== requested) {
6623
+ return {
6624
+ from: requested,
6625
+ to: reportPreferred,
6626
+ fromScore: 0,
6627
+ toScore: 0,
6628
+ reason: 'report route preference'
6629
+ };
6630
+ }
6631
+ }
6632
+ if (!allowVersions && isVersionCollectionName(requested)) {
6633
+ var base = stripVersionSuffix(requested);
6634
+ if (base && collectionNames.includes(base)) {
6635
+ return {
6636
+ from: requested,
6637
+ to: base,
6638
+ fromScore: 0,
6639
+ toScore: 0,
6640
+ reason: 'avoid versions collection'
6641
+ };
6642
+ }
6643
+ }
6644
+ var rankingOverride = resolveAssistantCollectionOverride(params.collectionRanking, requested);
6645
+ if (rankingOverride) {
6646
+ if (!allowVersions && isVersionCollectionName(rankingOverride.to)) {
6647
+ var base = stripVersionSuffix(rankingOverride.to);
6648
+ if (base && collectionNames.includes(base)) {
6649
+ return {
6650
+ from: requested,
6651
+ to: base,
6652
+ fromScore: rankingOverride.fromScore,
6653
+ toScore: rankingOverride.toScore,
6654
+ reason: 'avoid versions collection'
6655
+ };
6656
+ }
6657
+ }
6658
+ return rankingOverride;
6659
+ }
6660
+ return null;
6661
+ }
6662
+ function pickPreferredCollectionCandidate(ranked) {
6663
+ if (!Array.isArray(ranked) || !ranked.length) {
6664
+ return null;
6665
+ }
6666
+ var top = ranked[0];
6667
+ if (!top) {
6668
+ return null;
6669
+ }
6670
+ if (!isVersionCollectionName(top.name)) {
6671
+ return top;
6672
+ }
6673
+ var nonVersion = ranked.find(function (entry) { return entry && !isVersionCollectionName(entry.name); });
6674
+ if (nonVersion && nonVersion.score >= top.score - 5) {
6675
+ return nonVersion;
6676
+ }
6677
+ return top;
6678
+ }
6679
+ function resolveAssistantCollectionOverride(collectionRanking, currentCollection) {
6680
+ var _a, _b;
6681
+ var ranked = Array.isArray(collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked) ? collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked : [];
6682
+ if (!ranked.length) {
6683
+ return null;
6684
+ }
6685
+ var top = pickPreferredCollectionCandidate(ranked);
6686
+ if (!top || top.score < AI_ASSISTANT_COLLECTION_OVERRIDE_MIN_SCORE) {
6687
+ return null;
6688
+ }
6689
+ var current = normalizeOptionalString(currentCollection);
6690
+ if (!current) {
6691
+ return {
6692
+ from: '',
6693
+ to: top.name,
6694
+ fromScore: 0,
6695
+ toScore: top.score,
6696
+ reason: 'no collection specified'
6697
+ };
6698
+ }
6699
+ if (current === top.name) {
6700
+ return null;
6701
+ }
6702
+ var currentScore = (_b = (_a = ranked.find(function (entry) { return entry.name === current; })) === null || _a === void 0 ? void 0 : _a.score) !== null && _b !== void 0 ? _b : 0;
6703
+ var scoreGap = top.score - currentScore;
6704
+ var currentIsVersion = isVersionCollectionName(current);
6705
+ var topIsVersion = isVersionCollectionName(top.name);
6706
+ if (scoreGap < AI_ASSISTANT_COLLECTION_OVERRIDE_SCORE_GAP && !(currentIsVersion && !topIsVersion)) {
6707
+ return null;
6708
+ }
6709
+ var reason = currentIsVersion && !topIsVersion
6710
+ ? 'preferred non-version collection'
6711
+ : "higher score (".concat(top.score, " vs ").concat(currentScore, ")");
6712
+ return {
6713
+ from: current,
6714
+ to: top.name,
6715
+ fromScore: currentScore,
6716
+ toScore: top.score,
6717
+ reason: reason
3949
6718
  };
3950
6719
  }
3951
6720
  function findBestCollectionMatch(requested, collectionNames) {
@@ -3994,7 +6763,7 @@ function resolveAssistantCollectionName(db, dbName, requested) {
3994
6763
  });
3995
6764
  }
3996
6765
  function findQueryDateField(query) {
3997
- var e_7, _a, e_8, _b;
6766
+ var e_21, _a, e_22, _b;
3998
6767
  if (!query || typeof query !== 'object') {
3999
6768
  return null;
4000
6769
  }
@@ -4008,12 +6777,12 @@ function findQueryDateField(query) {
4008
6777
  }
4009
6778
  }
4010
6779
  }
4011
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
6780
+ catch (e_21_1) { e_21 = { error: e_21_1 }; }
4012
6781
  finally {
4013
6782
  try {
4014
6783
  if (query_1_1 && !query_1_1.done && (_a = query_1.return)) _a.call(query_1);
4015
6784
  }
4016
- finally { if (e_7) throw e_7.error; }
6785
+ finally { if (e_21) throw e_21.error; }
4017
6786
  }
4018
6787
  return null;
4019
6788
  }
@@ -4032,12 +6801,12 @@ function findQueryDateField(query) {
4032
6801
  }
4033
6802
  }
4034
6803
  }
4035
- catch (e_8_1) { e_8 = { error: e_8_1 }; }
6804
+ catch (e_22_1) { e_22 = { error: e_22_1 }; }
4036
6805
  finally {
4037
6806
  try {
4038
6807
  if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
4039
6808
  }
4040
- finally { if (e_8) throw e_8.error; }
6809
+ finally { if (e_22) throw e_22.error; }
4041
6810
  }
4042
6811
  return null;
4043
6812
  }
@@ -4128,15 +6897,15 @@ function expandQueryDateFallbacks(query) {
4128
6897
  };
4129
6898
  var visit = function (value) {
4130
6899
  if (Array.isArray(value)) {
4131
- var changed_1 = false;
6900
+ var changed_2 = false;
4132
6901
  var nextArray = value.map(function (entry) {
4133
6902
  var visited = visit(entry);
4134
6903
  if (visited.changed) {
4135
- changed_1 = true;
6904
+ changed_2 = true;
4136
6905
  }
4137
6906
  return visited.value;
4138
6907
  });
4139
- return { value: changed_1 ? nextArray : value, changed: changed_1 };
6908
+ return { value: changed_2 ? nextArray : value, changed: changed_2 };
4140
6909
  }
4141
6910
  if (!value || typeof value !== 'object') {
4142
6911
  return { value: value, changed: false };
@@ -4166,6 +6935,87 @@ function expandQueryDateFallbacks(query) {
4166
6935
  }
4167
6936
  return { query: result.value, fields: addedFields };
4168
6937
  }
6938
+ function buildDateFieldExpansionList(field) {
6939
+ var normalized = normalizeOptionalString(field);
6940
+ if (!normalized) {
6941
+ return [];
6942
+ }
6943
+ var expansions = new Set();
6944
+ var add = function (value) {
6945
+ if (value && value !== normalized) {
6946
+ expansions.add(value);
6947
+ }
6948
+ };
6949
+ var fallback = AI_ASSISTANT_DATE_FALLBACKS[normalized];
6950
+ if (fallback) {
6951
+ add(fallback);
6952
+ }
6953
+ if (normalized.startsWith('date_') || normalized === 'date' || normalized.endsWith('_date')) {
6954
+ AI_ASSISTANT_DATE_EXPANSION_FIELDS.forEach(add);
6955
+ }
6956
+ if (normalized === 'createdAt' || normalized === 'updatedAt') {
6957
+ AI_ASSISTANT_DATE_EXPANSION_FIELDS.forEach(add);
6958
+ }
6959
+ return Array.from(expansions);
6960
+ }
6961
+ function expandAggregateDateMatchFallback(pipeline) {
6962
+ if (!Array.isArray(pipeline)) {
6963
+ return null;
6964
+ }
6965
+ var _loop_7 = function (i) {
6966
+ var stage = pipeline[i];
6967
+ if (!stage || typeof stage !== 'object' || !stage.$match || typeof stage.$match !== 'object') {
6968
+ return "continue";
6969
+ }
6970
+ var matchStage = stage.$match;
6971
+ var orArray = Array.isArray(matchStage.$or) ? matchStage.$or : null;
6972
+ if (!orArray || !orArray.length) {
6973
+ return "continue";
6974
+ }
6975
+ var existingFields = new Set();
6976
+ orArray.forEach(function (entry) {
6977
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
6978
+ return;
6979
+ }
6980
+ Object.keys(entry).forEach(function (key) {
6981
+ if (!key.startsWith('$')) {
6982
+ existingFields.add(key);
6983
+ }
6984
+ });
6985
+ });
6986
+ var expandedOr = __spreadArray([], __read(orArray), false);
6987
+ var addedFields = new Set();
6988
+ orArray.forEach(function (entry) {
6989
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
6990
+ return;
6991
+ }
6992
+ var conditions = extractDateRangeConditions(entry);
6993
+ conditions.forEach(function (condition) {
6994
+ var expansions = buildDateFieldExpansionList(condition.field);
6995
+ expansions.forEach(function (field) {
6996
+ if (existingFields.has(field)) {
6997
+ return;
6998
+ }
6999
+ expandedOr = __spreadArray(__spreadArray([], __read(expandedOr), false), [replaceQueryField(entry, condition.field, field)], false);
7000
+ existingFields.add(field);
7001
+ addedFields.add(field);
7002
+ });
7003
+ });
7004
+ });
7005
+ if (!addedFields.size) {
7006
+ return { value: null };
7007
+ }
7008
+ var nextMatch = __assign(__assign({}, matchStage), { $or: expandedOr });
7009
+ var updated = pipeline.map(function (current, index) { return (index === i ? { $match: nextMatch } : current); });
7010
+ return { value: { pipeline: updated, fields: Array.from(addedFields) } };
7011
+ };
7012
+ for (var i = 0; i < pipeline.length; i += 1) {
7013
+ var state_5 = _loop_7(i);
7014
+ if (typeof state_5 === "object")
7015
+ return state_5.value;
7016
+ }
7017
+ return null;
7018
+ }
4169
7019
  function resolveQueryDateFieldFallback(query) {
4170
7020
  var dateField = findQueryDateField(query);
4171
7021
  if (!dateField) {
@@ -4178,7 +7028,7 @@ function resolveQueryDateFieldFallback(query) {
4178
7028
  return { from: dateField, to: fallback };
4179
7029
  }
4180
7030
  function containsForbiddenMongoOperators(value) {
4181
- var e_9, _a;
7031
+ var e_23, _a;
4182
7032
  if (!value || typeof value !== 'object') {
4183
7033
  return false;
4184
7034
  }
@@ -4197,12 +7047,12 @@ function containsForbiddenMongoOperators(value) {
4197
7047
  }
4198
7048
  }
4199
7049
  }
4200
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
7050
+ catch (e_23_1) { e_23 = { error: e_23_1 }; }
4201
7051
  finally {
4202
7052
  try {
4203
7053
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
4204
7054
  }
4205
- finally { if (e_9) throw e_9.error; }
7055
+ finally { if (e_23) throw e_23.error; }
4206
7056
  }
4207
7057
  return false;
4208
7058
  }
@@ -4211,9 +7061,49 @@ function buildClientScopeCacheKey(dbName, collection) {
4211
7061
  var normalizedCollection = normalizeOptionalString(collection).toLowerCase();
4212
7062
  return "".concat(normalizedDb || 'db', ":").concat(normalizedCollection);
4213
7063
  }
7064
+ function buildFieldIndexCacheKey(dbName, collection, field) {
7065
+ var normalizedDb = normalizeOptionalString(dbName).toLowerCase();
7066
+ var normalizedCollection = normalizeOptionalString(collection).toLowerCase();
7067
+ var normalizedField = normalizeOptionalString(field).toLowerCase();
7068
+ return "".concat(normalizedDb || 'db', ":").concat(normalizedCollection, ":").concat(normalizedField);
7069
+ }
7070
+ function collectionHasFieldIndex(db, dbName, collection, field) {
7071
+ return __awaiter(this, void 0, void 0, function () {
7072
+ var normalizedCollection, normalizedField, cacheKey, cached, indexes, hasIndex, _a;
7073
+ return __generator(this, function (_b) {
7074
+ switch (_b.label) {
7075
+ case 0:
7076
+ normalizedCollection = normalizeOptionalString(collection);
7077
+ normalizedField = normalizeOptionalString(field);
7078
+ if (!normalizedCollection || !normalizedField) {
7079
+ return [2 /*return*/, false];
7080
+ }
7081
+ cacheKey = buildFieldIndexCacheKey(dbName, normalizedCollection, normalizedField);
7082
+ cached = AI_ASSISTANT_FIELD_INDEX_CACHE.get(cacheKey);
7083
+ if (typeof cached === 'boolean') {
7084
+ return [2 /*return*/, cached];
7085
+ }
7086
+ _b.label = 1;
7087
+ case 1:
7088
+ _b.trys.push([1, 3, , 4]);
7089
+ return [4 /*yield*/, db.collection(normalizedCollection).indexes()];
7090
+ case 2:
7091
+ indexes = _b.sent();
7092
+ hasIndex = Array.isArray(indexes)
7093
+ && indexes.some(function (entry) { return (entry === null || entry === void 0 ? void 0 : entry.key) && Object.prototype.hasOwnProperty.call(entry.key, normalizedField); });
7094
+ AI_ASSISTANT_FIELD_INDEX_CACHE.set(cacheKey, hasIndex);
7095
+ return [2 /*return*/, hasIndex];
7096
+ case 3:
7097
+ _a = _b.sent();
7098
+ return [2 /*return*/, false];
7099
+ case 4: return [2 /*return*/];
7100
+ }
7101
+ });
7102
+ });
7103
+ }
4214
7104
  function collectionHasClientIndex(db, dbName, collection) {
4215
7105
  return __awaiter(this, void 0, void 0, function () {
4216
- var normalizedCollection, cacheKey, cached, indexes, hasIndex, _a;
7106
+ var normalizedCollection, cacheKey, cached, hasIndex, _a;
4217
7107
  return __generator(this, function (_b) {
4218
7108
  switch (_b.label) {
4219
7109
  case 0:
@@ -4229,11 +7119,9 @@ function collectionHasClientIndex(db, dbName, collection) {
4229
7119
  _b.label = 1;
4230
7120
  case 1:
4231
7121
  _b.trys.push([1, 3, , 4]);
4232
- return [4 /*yield*/, db.collection(normalizedCollection).indexes()];
7122
+ return [4 /*yield*/, collectionHasFieldIndex(db, dbName, normalizedCollection, 'id_client')];
4233
7123
  case 2:
4234
- indexes = _b.sent();
4235
- hasIndex = Array.isArray(indexes)
4236
- && indexes.some(function (entry) { return (entry === null || entry === void 0 ? void 0 : entry.key) && Object.prototype.hasOwnProperty.call(entry.key, 'id_client'); });
7124
+ hasIndex = _b.sent();
4237
7125
  AI_ASSISTANT_CLIENT_SCOPE_CACHE.set(cacheKey, hasIndex);
4238
7126
  return [2 /*return*/, hasIndex];
4239
7127
  case 3:
@@ -4275,6 +7163,25 @@ function applyCustomerScopeFilter(query, collection, idCustomer, isSuperAdmin) {
4275
7163
  $and: [query, (_a = {}, _a[customerField] = normalizedCustomer, _a)]
4276
7164
  };
4277
7165
  }
7166
+ function buildAssistantProbeQuery(collection, idClient, idCustomer, isSuperAdmin, includeClientScope) {
7167
+ if (isSuperAdmin === void 0) { isSuperAdmin = false; }
7168
+ if (includeClientScope === void 0) { includeClientScope = false; }
7169
+ var query = {};
7170
+ if (includeClientScope) {
7171
+ query = applyClientScopeFilter(query, idClient, isSuperAdmin);
7172
+ }
7173
+ return applyCustomerScopeFilter(query, collection, idCustomer, isSuperAdmin);
7174
+ }
7175
+ function fetchAssistantProbeDocs(params) {
7176
+ var db = params.db, collection = params.collection, idClient = params.idClient, idCustomer = params.idCustomer, isSuperAdmin = params.isSuperAdmin, includeClientScope = params.includeClientScope;
7177
+ var probeQuery = buildAssistantProbeQuery(collection, idClient, idCustomer, isSuperAdmin, includeClientScope);
7178
+ return db.collection(collection)
7179
+ .find(probeQuery, {
7180
+ limit: AI_ASSISTANT_PROBE_LIMIT,
7181
+ readPreference: AI_ASSISTANT_READ_PREFERENCE
7182
+ })
7183
+ .toArray();
7184
+ }
4278
7185
  function userHasViewPermission(user, view) {
4279
7186
  var _a, _b, _c;
4280
7187
  if (!user || !view) {
@@ -4436,8 +7343,8 @@ function applyCodexStreamStatusHandler(runOptions, streamStatusHandler) {
4436
7343
  }
4437
7344
  function waitForCodexWorkerMessage(worker, streamStatusHandler) {
4438
7345
  return __awaiter(this, void 0, void 0, function () {
4439
- var _a, _b, _c, _d, message, payload, status_1, e_10_1;
4440
- var _e, e_10, _f, _g;
7346
+ var _a, _b, _c, _d, message, payload, status_1, e_24_1;
7347
+ var _e, e_24, _f, _g;
4441
7348
  return __generator(this, function (_h) {
4442
7349
  switch (_h.label) {
4443
7350
  case 0:
@@ -4464,8 +7371,8 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
4464
7371
  return [3 /*break*/, 1];
4465
7372
  case 4: return [3 /*break*/, 11];
4466
7373
  case 5:
4467
- e_10_1 = _h.sent();
4468
- e_10 = { error: e_10_1 };
7374
+ e_24_1 = _h.sent();
7375
+ e_24 = { error: e_24_1 };
4469
7376
  return [3 /*break*/, 11];
4470
7377
  case 6:
4471
7378
  _h.trys.push([6, , 9, 10]);
@@ -4476,7 +7383,7 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
4476
7383
  _h.label = 8;
4477
7384
  case 8: return [3 /*break*/, 10];
4478
7385
  case 9:
4479
- if (e_10) throw e_10.error;
7386
+ if (e_24) throw e_24.error;
4480
7387
  return [7 /*endfinally*/];
4481
7388
  case 10: return [7 /*endfinally*/];
4482
7389
  case 11: throw new CodexWorkerBootstrapError('Codex worker exited before completing.');
@@ -4864,7 +7771,7 @@ function normalizeRouteMatchKey(value) {
4864
7771
  return normalizeRouteKey(value).toLowerCase();
4865
7772
  }
4866
7773
  function buildClientRouteIndex() {
4867
- var e_11, _a;
7774
+ var e_25, _a;
4868
7775
  var _b;
4869
7776
  var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
4870
7777
  var set = new Set();
@@ -4883,12 +7790,12 @@ function buildClientRouteIndex() {
4883
7790
  }
4884
7791
  }
4885
7792
  }
4886
- catch (e_11_1) { e_11 = { error: e_11_1 }; }
7793
+ catch (e_25_1) { e_25 = { error: e_25_1 }; }
4887
7794
  finally {
4888
7795
  try {
4889
7796
  if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
4890
7797
  }
4891
- finally { if (e_11) throw e_11.error; }
7798
+ finally { if (e_25) throw e_25.error; }
4892
7799
  }
4893
7800
  return { set: set, map: map, size: routes.length };
4894
7801
  }
@@ -4978,6 +7885,20 @@ function sanitizeAssistantResponse(value) {
4978
7885
  }
4979
7886
  return /^i\s+(can|will|['’]ll|am going to|['’]m going to)\s+(pull|run|query|get|fetch|look up|retrieve|grab)\b/i.test(normalized);
4980
7887
  };
7888
+ var isInternalPlanLine = function (line) {
7889
+ var trimmed = line.trim();
7890
+ if (!trimmed || trimmed.length > 120) {
7891
+ return false;
7892
+ }
7893
+ var normalized = trimmed.toLowerCase();
7894
+ var hasPhrase = /schema[-\s]?probe|query rewrite|id[-\s]?lookup|collection override|probe read|tiny probe|fallback plan/i.test(normalized);
7895
+ if (!hasPhrase) {
7896
+ return false;
7897
+ }
7898
+ var isBulletish = /^[-*•]+\s+/.test(trimmed);
7899
+ var isPlanish = /^(plan|planning|approach|strategy|steps?|todo|checklist)\b/i.test(trimmed);
7900
+ return isBulletish || isPlanish;
7901
+ };
4981
7902
  var cleanedLines = [];
4982
7903
  withoutBlocks.split('\n').forEach(function (line) {
4983
7904
  var trimmed = line.trim();
@@ -4988,6 +7909,9 @@ function sanitizeAssistantResponse(value) {
4988
7909
  if (isTentativeQueryLine(line)) {
4989
7910
  return;
4990
7911
  }
7912
+ if (isInternalPlanLine(line)) {
7913
+ return;
7914
+ }
4991
7915
  if (/^work ticket summary:/i.test(trimmed)) {
4992
7916
  return;
4993
7917
  }
@@ -5014,7 +7938,7 @@ function sanitizeAssistantResponse(value) {
5014
7938
  return normalizeAssistantRoutes(normalizedCurrency);
5015
7939
  }
5016
7940
  function evaluateAssistantGuardrails(message) {
5017
- var e_12, _a;
7941
+ var e_26, _a;
5018
7942
  var normalized = String(message || '').toLowerCase();
5019
7943
  var patterns = [
5020
7944
  {
@@ -5060,12 +7984,12 @@ function evaluateAssistantGuardrails(message) {
5060
7984
  }
5061
7985
  }
5062
7986
  }
5063
- catch (e_12_1) { e_12 = { error: e_12_1 }; }
7987
+ catch (e_26_1) { e_26 = { error: e_26_1 }; }
5064
7988
  finally {
5065
7989
  try {
5066
7990
  if (patterns_1_1 && !patterns_1_1.done && (_a = patterns_1.return)) _a.call(patterns_1);
5067
7991
  }
5068
- finally { if (e_12) throw e_12.error; }
7992
+ finally { if (e_26) throw e_26.error; }
5069
7993
  }
5070
7994
  return null;
5071
7995
  }
@@ -5180,7 +8104,7 @@ function tokenizeArithmeticExpression(expression) {
5180
8104
  return tokens;
5181
8105
  }
5182
8106
  function evaluateArithmeticExpression(expression) {
5183
- var e_13, _a, e_14, _b;
8107
+ var e_27, _a, e_28, _b;
5184
8108
  var tokens = tokenizeArithmeticExpression(expression);
5185
8109
  if (!tokens || !tokens.length) {
5186
8110
  return null;
@@ -5237,12 +8161,12 @@ function evaluateArithmeticExpression(expression) {
5237
8161
  prevToken = token;
5238
8162
  }
5239
8163
  }
5240
- catch (e_13_1) { e_13 = { error: e_13_1 }; }
8164
+ catch (e_27_1) { e_27 = { error: e_27_1 }; }
5241
8165
  finally {
5242
8166
  try {
5243
8167
  if (tokens_1_1 && !tokens_1_1.done && (_a = tokens_1.return)) _a.call(tokens_1);
5244
8168
  }
5245
- finally { if (e_13) throw e_13.error; }
8169
+ finally { if (e_27) throw e_27.error; }
5246
8170
  }
5247
8171
  while (ops.length) {
5248
8172
  var op = ops.pop();
@@ -5282,12 +8206,12 @@ function evaluateArithmeticExpression(expression) {
5282
8206
  stack.push(Number(token));
5283
8207
  }
5284
8208
  }
5285
- catch (e_14_1) { e_14 = { error: e_14_1 }; }
8209
+ catch (e_28_1) { e_28 = { error: e_28_1 }; }
5286
8210
  finally {
5287
8211
  try {
5288
8212
  if (output_1_1 && !output_1_1.done && (_b = output_1.return)) _b.call(output_1);
5289
8213
  }
5290
- finally { if (e_14) throw e_14.error; }
8214
+ finally { if (e_28) throw e_28.error; }
5291
8215
  }
5292
8216
  if (stack.length !== 1 || Number.isNaN(stack[0])) {
5293
8217
  return null;
@@ -5471,8 +8395,8 @@ function handleCodexUpload(id_conversation, file_name, content_base64, size, con
5471
8395
  }
5472
8396
  function readAttachmentContents(attachments) {
5473
8397
  return __awaiter(this, void 0, void 0, function () {
5474
- var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_15_1;
5475
- var e_15, _b;
8398
+ var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_29_1;
8399
+ var e_29, _b;
5476
8400
  return __generator(this, function (_c) {
5477
8401
  switch (_c.label) {
5478
8402
  case 0:
@@ -5551,14 +8475,14 @@ function readAttachmentContents(attachments) {
5551
8475
  return [3 /*break*/, 2];
5552
8476
  case 10: return [3 /*break*/, 13];
5553
8477
  case 11:
5554
- e_15_1 = _c.sent();
5555
- e_15 = { error: e_15_1 };
8478
+ e_29_1 = _c.sent();
8479
+ e_29 = { error: e_29_1 };
5556
8480
  return [3 /*break*/, 13];
5557
8481
  case 12:
5558
8482
  try {
5559
8483
  if (attachments_1_1 && !attachments_1_1.done && (_b = attachments_1.return)) _b.call(attachments_1);
5560
8484
  }
5561
- finally { if (e_15) throw e_15.error; }
8485
+ finally { if (e_29) throw e_29.error; }
5562
8486
  return [7 /*endfinally*/];
5563
8487
  case 13: return [2 /*return*/, {
5564
8488
  promptText: chunks.length ? "\n\nAttachments:\n".concat(chunks.join('\n\n')) : '',
@@ -5679,6 +8603,17 @@ function normalizeOptionalString(value) {
5679
8603
  var raw = typeof value === 'string' ? value.trim() : '';
5680
8604
  return raw || '';
5681
8605
  }
8606
+ function resolveSingleWorkerTarget(value) {
8607
+ var normalized = normalizeOptionalString(value);
8608
+ if (!normalized) {
8609
+ return '';
8610
+ }
8611
+ var parts = normalized.split(',').map(function (part) { return part.trim(); }).filter(Boolean);
8612
+ if (parts.length !== 1) {
8613
+ return '';
8614
+ }
8615
+ return parts[0];
8616
+ }
5682
8617
  function normalizeConversationMode(value) {
5683
8618
  var normalized = normalizeOptionalString(value).toLowerCase();
5684
8619
  if (normalized === 'codex') {
@@ -5735,7 +8670,7 @@ function estimateUsage(messages, responseText, model) {
5735
8670
  };
5736
8671
  }
5737
8672
  function evaluateGuardrails(message) {
5738
- var e_16, _a;
8673
+ var e_30, _a;
5739
8674
  var normalized = String(message || '').toLowerCase();
5740
8675
  var patterns = [
5741
8676
  { 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.' },
@@ -5757,12 +8692,12 @@ function evaluateGuardrails(message) {
5757
8692
  }
5758
8693
  }
5759
8694
  }
5760
- catch (e_16_1) { e_16 = { error: e_16_1 }; }
8695
+ catch (e_30_1) { e_30 = { error: e_30_1 }; }
5761
8696
  finally {
5762
8697
  try {
5763
8698
  if (patterns_2_1 && !patterns_2_1.done && (_a = patterns_2.return)) _a.call(patterns_2);
5764
8699
  }
5765
- finally { if (e_16) throw e_16.error; }
8700
+ finally { if (e_30) throw e_30.error; }
5766
8701
  }
5767
8702
  return null;
5768
8703
  }