@resolveio/server-lib 20.15.9 → 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.
@@ -147,6 +147,9 @@ var AI_ASSISTANT_TOOL_MAX_STEPS = 1;
147
147
  var AI_ASSISTANT_DISPLAY_MAX_COLUMNS = 12;
148
148
  var AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS = 20;
149
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;
150
153
  var AI_ASSISTANT_PROGRESS_PLACEHOLDER = 'Planning...';
151
154
  var AI_ASSISTANT_PROGRESS_TICK_MS = 5000;
152
155
  var AI_ASSISTANT_READ_PREFERENCE = 'secondary';
@@ -346,7 +349,9 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
346
349
  '- Do not assist with hacking, bypassing security, or abuse.',
347
350
  'Accuracy & tools:',
348
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.',
349
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.',
350
355
  '- Map user wording to internal collections/fields yourself. Do not ask for property names unless required to run a query.',
351
356
  '- Use term hints from context (synonym expansions) when mapping user language to collections.',
352
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.',
@@ -354,12 +359,14 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
354
359
  '- For any data request (counts, lists, breakdowns, recent/last items), you MUST run a MONGO_READ or MONGO_AGG before answering.',
355
360
  '- Ask at most one clarifying question only when required to run a query or resolve missing details.',
356
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.',
357
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.',
358
364
  '- Use the codebase context to choose correct collections/fields/workflows and use MONGO_READ/MONGO_AGG to answer with real data when needed.',
359
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.',
360
366
  '- Assume a relevant collection exists; if verification reads return zero data, report no data found instead of interrogating the user.',
361
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.',
362
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.',
363
370
  '- For direct questions, answer first. Ask a single follow-up only if required to proceed.',
364
371
  'Data Presentation:',
365
372
  '- Output plain Markdown (NO triple backticks).',
@@ -495,6 +502,12 @@ function drainAssistantCodexRunQueue() {
495
502
  });
496
503
  }
497
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);
498
511
  methodManager.methods({
499
512
  aiTerminalConversationCreate: {
500
513
  check: new simpl_schema_1.default({
@@ -726,17 +739,12 @@ function loadAiTerminalMethods(methodManager) {
726
739
  });
727
740
  }
728
741
  },
729
- aiCoderTerminalRunCodex: {
730
- check: new simpl_schema_1.default({
742
+ aiCoderTerminalRunCodex: __assign(__assign(__assign({ check: new simpl_schema_1.default({
731
743
  payload: {
732
744
  type: Object,
733
745
  blackbox: true
734
746
  }
735
- }),
736
- forceWorker: true,
737
- maxConcurrencyPerInstance: 1,
738
- timeoutOverride: resolveCodexTimeoutMs() + 15000,
739
- function: function (payload) {
747
+ }), forceWorker: true, workerQueue: 'codex' }, (codexWorkerIndex ? { targetWorkerIndex: codexWorkerIndex } : {})), (codexWorkerInstance ? { targetWorkerInstance: codexWorkerInstance } : {})), { maxConcurrencyPerInstance: 1, timeoutOverride: resolveCodexTimeoutMs() + 15000, function: function (payload) {
740
748
  return __awaiter(this, void 0, void 0, function () {
741
749
  return __generator(this, function (_a) {
742
750
  switch (_a.label) {
@@ -745,8 +753,7 @@ function loadAiTerminalMethods(methodManager) {
745
753
  }
746
754
  });
747
755
  });
748
- }
749
- },
756
+ } }),
750
757
  aiAssistantMongoRead: {
751
758
  check: new simpl_schema_1.default({
752
759
  payload: {
@@ -1131,10 +1138,10 @@ function executeAiAssistantCodexRun(payload, context) {
1131
1138
  insertResult = _d.sent();
1132
1139
  assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
1133
1140
  enqueueAssistantCodexRun(function () { return __awaiter(_this, void 0, void 0, function () {
1134
- var runStart, steps, recordStep, progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, dataQuestion, lastDirective, toolResponseDebug, toolError, termHints, collectionHints, collectionTokenization, collectionRanking, collectionSelection, collectionOverride, timingBreakdown, contextRoute, contextMode, hintSeed, termExpansion, hintText, baseTokens, expandedTokens, baseWeights, expandedWeights, dbName, db, collectionNames, _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;
1135
- var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
1136
- return __generator(this, function (_t) {
1137
- switch (_t.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) {
1138
1145
  case 0:
1139
1146
  runStart = Date.now();
1140
1147
  steps = [];
@@ -1162,6 +1169,7 @@ function executeAiAssistantCodexRun(payload, context) {
1162
1169
  collectionRanking = null;
1163
1170
  collectionSelection = null;
1164
1171
  collectionOverride = null;
1172
+ collectionNames = [];
1165
1173
  timingBreakdown = {
1166
1174
  directiveMs: 0,
1167
1175
  initialResponseMs: 0,
@@ -1172,9 +1180,9 @@ function executeAiAssistantCodexRun(payload, context) {
1172
1180
  contextRoute = normalizeOptionalString((_f = input === null || input === void 0 ? void 0 : input.context) === null || _f === void 0 ? void 0 : _f.route);
1173
1181
  contextMode = normalizeOptionalString((_g = input === null || input === void 0 ? void 0 : input.context) === null || _g === void 0 ? void 0 : _g.mode);
1174
1182
  recordStep('Queued', { requestId: requestId || undefined });
1175
- _t.label = 1;
1183
+ _u.label = 1;
1176
1184
  case 1:
1177
- _t.trys.push([1, 30, 31, 32]);
1185
+ _u.trys.push([1, 30, 31, 32]);
1178
1186
  hintSeed = [message, contextRoute].filter(Boolean).join(' ');
1179
1187
  termExpansion = expandAssistantTermSynonyms(hintSeed);
1180
1188
  hintText = termExpansion.expanded || hintSeed;
@@ -1195,19 +1203,19 @@ function executeAiAssistantCodexRun(payload, context) {
1195
1203
  recordStep('Planning: term expansion', {
1196
1204
  termMatches: termExpansion.matches.length ? termExpansion.matches : undefined
1197
1205
  });
1198
- _t.label = 2;
1206
+ _u.label = 2;
1199
1207
  case 2:
1200
- _t.trys.push([2, 4, , 5]);
1208
+ _u.trys.push([2, 4, , 5]);
1201
1209
  dbName = resolveAssistantDatabaseName(undefined, input.mongo);
1202
1210
  db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
1203
1211
  return [4 /*yield*/, listAssistantCollections(db, dbName)];
1204
1212
  case 3:
1205
- collectionNames = _t.sent();
1213
+ collectionNames = _u.sent();
1206
1214
  collectionHints = resolveCollectionHintsFromTokens(expandedTokens, collectionNames, 5);
1207
1215
  collectionRanking = buildCollectionRankingDebugFromTokens(expandedTokens, collectionNames, 8);
1208
1216
  return [3 /*break*/, 5];
1209
1217
  case 4:
1210
- _a = _t.sent();
1218
+ _a = _u.sent();
1211
1219
  collectionHints = [];
1212
1220
  collectionRanking = collectionRanking || ((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens)
1213
1221
  ? buildCollectionRankingDebugFromTokens(collectionTokenization.expandedTokens || [], [], 0)
@@ -1230,7 +1238,7 @@ function executeAiAssistantCodexRun(payload, context) {
1230
1238
  prompt_1 = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1231
1239
  return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
1232
1240
  case 6:
1233
- workspaceRoot = _t.sent();
1241
+ workspaceRoot = _u.sent();
1234
1242
  codexConfig = resolveCodexSettings();
1235
1243
  runOptions = {
1236
1244
  timeoutMs: resolveCodexTimeoutMs(),
@@ -1251,13 +1259,13 @@ function executeAiAssistantCodexRun(payload, context) {
1251
1259
  if (!dataQuestion) return [3 /*break*/, 10];
1252
1260
  recordStep('Directive: determine tool', { type: 'data-question' });
1253
1261
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1254
- _t.label = 7;
1262
+ _u.label = 7;
1255
1263
  case 7:
1256
- _t.trys.push([7, 9, , 10]);
1264
+ _u.trys.push([7, 9, , 10]);
1257
1265
  directiveStart = Date.now();
1258
1266
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1259
1267
  case 8:
1260
- directiveText = _t.sent();
1268
+ directiveText = _u.sent();
1261
1269
  timingBreakdown.directiveMs = Date.now() - directiveStart;
1262
1270
  forcedDirective = extractAssistantMongoDirective(directiveText);
1263
1271
  if (forcedDirective) {
@@ -1274,7 +1282,7 @@ function executeAiAssistantCodexRun(payload, context) {
1274
1282
  }
1275
1283
  return [3 /*break*/, 10];
1276
1284
  case 9:
1277
- _b = _t.sent();
1285
+ _b = _u.sent();
1278
1286
  return [3 /*break*/, 10];
1279
1287
  case 10:
1280
1288
  if (!!directive) return [3 /*break*/, 12];
@@ -1282,7 +1290,7 @@ function executeAiAssistantCodexRun(payload, context) {
1282
1290
  initialStart = Date.now();
1283
1291
  return [4 /*yield*/, runCodexInWorkerThread(prompt_1, runOptions, codexConfig, streamProgress)];
1284
1292
  case 11:
1285
- responseText = _t.sent();
1293
+ responseText = _u.sent();
1286
1294
  timingBreakdown.initialResponseMs = Date.now() - initialStart;
1287
1295
  directive = extractAssistantMongoDirective(responseText);
1288
1296
  if (directive) {
@@ -1296,18 +1304,18 @@ function executeAiAssistantCodexRun(payload, context) {
1296
1304
  permissionView: normalizeOptionalString((_o = directive.payload) === null || _o === void 0 ? void 0 : _o.permissionView) || undefined
1297
1305
  });
1298
1306
  }
1299
- _t.label = 12;
1307
+ _u.label = 12;
1300
1308
  case 12:
1301
1309
  if (!(!directive && dataQuestion)) return [3 /*break*/, 16];
1302
1310
  recordStep('Directive: forced retry', { mode: 'directive-only' });
1303
1311
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1304
- _t.label = 13;
1312
+ _u.label = 13;
1305
1313
  case 13:
1306
- _t.trys.push([13, 15, , 16]);
1314
+ _u.trys.push([13, 15, , 16]);
1307
1315
  forcedStart = Date.now();
1308
1316
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1309
1317
  case 14:
1310
- directiveText = _t.sent();
1318
+ directiveText = _u.sent();
1311
1319
  timingBreakdown.forcedDirectiveMs = Date.now() - forcedStart;
1312
1320
  forcedDirective = extractAssistantMongoDirective(directiveText);
1313
1321
  if (forcedDirective) {
@@ -1324,12 +1332,18 @@ function executeAiAssistantCodexRun(payload, context) {
1324
1332
  }
1325
1333
  return [3 /*break*/, 16];
1326
1334
  case 15:
1327
- _c = _t.sent();
1335
+ _c = _u.sent();
1328
1336
  return [3 /*break*/, 16];
1329
1337
  case 16:
1330
1338
  if (directive) {
1331
1339
  requestedCollection = normalizeOptionalString((_s = directive.payload) === null || _s === void 0 ? void 0 : _s.collection);
1332
- collectionOverride = resolveAssistantCollectionOverride(collectionRanking, requestedCollection);
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
+ });
1333
1347
  if (collectionOverride) {
1334
1348
  recordStep('Planning: collection override', {
1335
1349
  from: collectionOverride.from || undefined,
@@ -1353,19 +1367,19 @@ function executeAiAssistantCodexRun(payload, context) {
1353
1367
  collection: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.collection) || undefined,
1354
1368
  permissionView: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.permissionView) || undefined
1355
1369
  });
1356
- _t.label = 17;
1370
+ _u.label = 17;
1357
1371
  case 17:
1358
- _t.trys.push([17, 26, , 27]);
1372
+ _u.trys.push([17, 26, , 27]);
1359
1373
  toolStart = Date.now();
1360
1374
  if (!(effectiveDirective.type === 'aggregate')) return [3 /*break*/, 19];
1361
1375
  return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
1362
1376
  case 18:
1363
- _d = _t.sent();
1377
+ _d = _u.sent();
1364
1378
  return [3 /*break*/, 21];
1365
1379
  case 19: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
1366
1380
  case 20:
1367
- _d = _t.sent();
1368
- _t.label = 21;
1381
+ _d = _u.sent();
1382
+ _u.label = 21;
1369
1383
  case 21:
1370
1384
  toolResponse = _d;
1371
1385
  timingBreakdown.toolMs = Date.now() - toolStart;
@@ -1382,23 +1396,23 @@ function executeAiAssistantCodexRun(payload, context) {
1382
1396
  progressTracker.push('Drafting response');
1383
1397
  recordStep('Drafting response');
1384
1398
  followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
1385
- _t.label = 22;
1399
+ _u.label = 22;
1386
1400
  case 22:
1387
- _t.trys.push([22, 24, , 25]);
1401
+ _u.trys.push([22, 24, , 25]);
1388
1402
  followupStart = Date.now();
1389
1403
  return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
1390
1404
  case 23:
1391
- followupText = _t.sent();
1405
+ followupText = _u.sent();
1392
1406
  timingBreakdown.followupMs = Date.now() - followupStart;
1393
1407
  assistantContent = sanitizeAssistantResponse(followupText);
1394
1408
  return [3 /*break*/, 25];
1395
1409
  case 24:
1396
- _e = _t.sent();
1410
+ _e = _u.sent();
1397
1411
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
1398
1412
  return [3 /*break*/, 25];
1399
1413
  case 25: return [3 /*break*/, 27];
1400
1414
  case 26:
1401
- error_2 = _t.sent();
1415
+ error_2 = _u.sent();
1402
1416
  assistantContent = buildAssistantToolErrorMessage(error_2, directive, toolRequest);
1403
1417
  toolError = error_2;
1404
1418
  return [3 /*break*/, 27];
@@ -1406,10 +1420,10 @@ function executeAiAssistantCodexRun(payload, context) {
1406
1420
  case 28:
1407
1421
  progressTracker.push('Drafting response');
1408
1422
  recordStep('Drafting response');
1409
- _t.label = 29;
1423
+ _u.label = 29;
1410
1424
  case 29: return [3 /*break*/, 32];
1411
1425
  case 30:
1412
- error_3 = _t.sent();
1426
+ error_3 = _u.sent();
1413
1427
  assistantContent = buildAssistantCodexErrorMessage(error_3);
1414
1428
  recordStep('Error', { message: normalizeOptionalString(error_3 === null || error_3 === void 0 ? void 0 : error_3.message) || 'Unknown error' });
1415
1429
  return [3 /*break*/, 32];
@@ -1474,16 +1488,16 @@ function executeAiAssistantCodexRun(payload, context) {
1474
1488
  }
1475
1489
  })];
1476
1490
  case 33:
1477
- _t.sent();
1478
- _t.label = 34;
1491
+ _u.sent();
1492
+ _u.label = 34;
1479
1493
  case 34: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
1480
1494
  case 35:
1481
- _t.sent();
1495
+ _u.sent();
1482
1496
  if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 37];
1483
1497
  return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
1484
1498
  case 36:
1485
- _t.sent();
1486
- _t.label = 37;
1499
+ _u.sent();
1500
+ _u.label = 37;
1487
1501
  case 37: return [2 /*return*/, finalAssistantDoc];
1488
1502
  }
1489
1503
  });
@@ -1497,10 +1511,10 @@ function executeAiAssistantCodexRun(payload, context) {
1497
1511
  }
1498
1512
  function executeAiAssistantMongoRead(payload, context) {
1499
1513
  return __awaiter(this, void 0, void 0, function () {
1500
- var input, rawCollection, dbName, db, collectionResolution, collection, _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, queryFields, _c, aliases, rewrittenQuery, fallbackDocs, _d, idLookup, fallbackDocs, total, sanitizedDocuments, requestedFields, missingFields, _e, projectionAliases, expandedProjection, refreshedDocs, includeIds, fieldAliases, displayDocs, priorityFields, display;
1501
- var _f, _g;
1502
- return __generator(this, function (_h) {
1503
- switch (_h.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) {
1504
1518
  case 0:
1505
1519
  input = payload || {};
1506
1520
  rawCollection = normalizeOptionalString(input.collection);
@@ -1511,15 +1525,16 @@ function executeAiAssistantMongoRead(payload, context) {
1511
1525
  db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
1512
1526
  return [4 /*yield*/, resolveAssistantCollectionName(db, dbName, rawCollection)];
1513
1527
  case 1:
1514
- collectionResolution = _h.sent();
1528
+ collectionResolution = _q.sent();
1515
1529
  collection = collectionResolution.name || rawCollection;
1530
+ schemaFields = getCollectionSchemaFieldNames(collection);
1516
1531
  return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
1517
1532
  case 2:
1518
- _a = _h.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
1533
+ _a = _q.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
1519
1534
  if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
1520
1535
  throw new Error('AI assistant mongo read: Access denied.');
1521
1536
  }
1522
- customerId = normalizeOptionalString((_f = user === null || user === void 0 ? void 0 : user.other) === null || _f === void 0 ? void 0 : _f.id_customer);
1537
+ customerId = normalizeOptionalString((_o = user === null || user === void 0 ? void 0 : user.other) === null || _o === void 0 ? void 0 : _o.id_customer);
1523
1538
  fallbackMeta = {};
1524
1539
  baseQuery = normalizeMongoQuery(input.query);
1525
1540
  if (!isSuperAdmin && customerId) {
@@ -1544,11 +1559,11 @@ function executeAiAssistantMongoRead(payload, context) {
1544
1559
  if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 4];
1545
1560
  return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
1546
1561
  case 3:
1547
- _b = _h.sent();
1562
+ _b = _q.sent();
1548
1563
  return [3 /*break*/, 5];
1549
1564
  case 4:
1550
1565
  _b = false;
1551
- _h.label = 5;
1566
+ _q.label = 5;
1552
1567
  case 5:
1553
1568
  shouldScopeByClient = _b;
1554
1569
  if (!isSuperAdmin && shouldScopeByClient) {
@@ -1568,7 +1583,7 @@ function executeAiAssistantMongoRead(payload, context) {
1568
1583
  findOptions = __assign(__assign({}, normalized.findOptions), { readPreference: AI_ASSISTANT_READ_PREFERENCE });
1569
1584
  return [4 /*yield*/, db.collection(collection).find(scopedQuery, findOptions).toArray()];
1570
1585
  case 6:
1571
- documents = _h.sent();
1586
+ documents = _q.sent();
1572
1587
  executedQuery = scopedQuery;
1573
1588
  probeDocs = null;
1574
1589
  if (!!documents.length) return [3 /*break*/, 8];
@@ -1578,13 +1593,13 @@ function executeAiAssistantMongoRead(payload, context) {
1578
1593
  fallbackMeta.dateField = __assign(__assign({}, dateFallback), { attempted: true, used: false });
1579
1594
  return [4 /*yield*/, db.collection(collection).find(fallbackQuery, findOptions).toArray()];
1580
1595
  case 7:
1581
- fallbackDocs = _h.sent();
1596
+ fallbackDocs = _q.sent();
1582
1597
  if (fallbackDocs.length) {
1583
1598
  documents = fallbackDocs;
1584
1599
  executedQuery = fallbackQuery;
1585
1600
  fallbackMeta.dateField.used = true;
1586
1601
  }
1587
- _h.label = 8;
1602
+ _q.label = 8;
1588
1603
  case 8:
1589
1604
  if (!!documents.length) return [3 /*break*/, 10];
1590
1605
  expanded = expandQueryDateFallbacks(executedQuery);
@@ -1596,13 +1611,13 @@ function executeAiAssistantMongoRead(payload, context) {
1596
1611
  };
1597
1612
  return [4 /*yield*/, db.collection(collection).find(expanded.query, findOptions).toArray()];
1598
1613
  case 9:
1599
- fallbackDocs = _h.sent();
1614
+ fallbackDocs = _q.sent();
1600
1615
  if (fallbackDocs.length) {
1601
1616
  documents = fallbackDocs;
1602
1617
  executedQuery = expanded.query;
1603
1618
  fallbackMeta.dateFieldsExpanded.used = true;
1604
1619
  }
1605
- _h.label = 10;
1620
+ _q.label = 10;
1606
1621
  case 10:
1607
1622
  if (!!documents.length) return [3 /*break*/, 12];
1608
1623
  nameFallback = resolveReadNameMatchFallback(executedQuery);
@@ -1615,17 +1630,15 @@ function executeAiAssistantMongoRead(payload, context) {
1615
1630
  };
1616
1631
  return [4 /*yield*/, db.collection(collection).find(nameFallback.query, findOptions).toArray()];
1617
1632
  case 11:
1618
- fallbackDocs = _h.sent();
1633
+ fallbackDocs = _q.sent();
1619
1634
  if (fallbackDocs.length) {
1620
1635
  documents = fallbackDocs;
1621
1636
  executedQuery = nameFallback.query;
1622
1637
  fallbackMeta.nameMatch.used = true;
1623
1638
  }
1624
- _h.label = 12;
1639
+ _q.label = 12;
1625
1640
  case 12:
1626
- if (!!documents.length) return [3 /*break*/, 16];
1627
- queryFields = extractQueryFieldPaths(executedQuery).filter(function (field) { return !isAssistantIdField(field); });
1628
- if (!queryFields.length) return [3 /*break*/, 16];
1641
+ if (!!documents.length) return [3 /*break*/, 17];
1629
1642
  _c = probeDocs;
1630
1643
  if (_c) return [3 /*break*/, 14];
1631
1644
  return [4 /*yield*/, fetchAssistantProbeDocs({
@@ -1637,13 +1650,54 @@ function executeAiAssistantMongoRead(payload, context) {
1637
1650
  includeClientScope: shouldScopeByClient
1638
1651
  })];
1639
1652
  case 13:
1640
- _c = (_h.sent());
1641
- _h.label = 14;
1653
+ _c = (_q.sent());
1654
+ _q.label = 14;
1642
1655
  case 14:
1643
1656
  probeDocs = _c;
1644
- if (!probeDocs.length) return [3 /*break*/, 16];
1645
- aliases = resolveFieldAliases(probeDocs, queryFields);
1646
- if (!Object.keys(aliases).length) return [3 /*break*/, 16];
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];
1647
1701
  fallbackMeta.queryFieldAliases = {
1648
1702
  aliases: aliases,
1649
1703
  attempted: true,
@@ -1655,18 +1709,18 @@ function executeAiAssistantMongoRead(payload, context) {
1655
1709
  return replaceFieldPathDeep(acc, from, to);
1656
1710
  }, executedQuery);
1657
1711
  return [4 /*yield*/, db.collection(collection).find(rewrittenQuery, findOptions).toArray()];
1658
- case 15:
1659
- fallbackDocs = _h.sent();
1712
+ case 20:
1713
+ fallbackDocs = _q.sent();
1660
1714
  if (fallbackDocs.length) {
1661
1715
  documents = fallbackDocs;
1662
1716
  executedQuery = rewrittenQuery;
1663
1717
  fallbackMeta.queryFieldAliases.used = true;
1664
1718
  }
1665
- _h.label = 16;
1666
- case 16:
1667
- if (!!documents.length) return [3 /*break*/, 21];
1668
- _d = probeDocs;
1669
- if (_d) return [3 /*break*/, 18];
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];
1670
1724
  return [4 /*yield*/, fetchAssistantProbeDocs({
1671
1725
  db: db,
1672
1726
  collection: collection,
@@ -1675,11 +1729,11 @@ function executeAiAssistantMongoRead(payload, context) {
1675
1729
  isSuperAdmin: isSuperAdmin,
1676
1730
  includeClientScope: shouldScopeByClient
1677
1731
  })];
1678
- case 17:
1679
- _d = (_h.sent());
1680
- _h.label = 18;
1681
- case 18:
1682
- probeDocs = _d;
1732
+ case 22:
1733
+ _e = (_q.sent());
1734
+ _q.label = 23;
1735
+ case 23:
1736
+ probeDocs = _e;
1683
1737
  return [4 /*yield*/, applyIdLookupFallbackToQuery({
1684
1738
  query: executedQuery,
1685
1739
  db: db,
@@ -1689,36 +1743,143 @@ function executeAiAssistantMongoRead(payload, context) {
1689
1743
  isSuperAdmin: isSuperAdmin,
1690
1744
  probeDocs: probeDocs || undefined
1691
1745
  })];
1692
- case 19:
1693
- idLookup = _h.sent();
1694
- if (!idLookup) return [3 /*break*/, 21];
1746
+ case 24:
1747
+ idLookup = _q.sent();
1748
+ if (!idLookup) return [3 /*break*/, 26];
1695
1749
  fallbackMeta.idLookup = __assign(__assign({}, idLookup.meta), { attempted: true, used: false });
1696
1750
  return [4 /*yield*/, db.collection(collection).find(idLookup.query, findOptions).toArray()];
1697
- case 20:
1698
- fallbackDocs = _h.sent();
1751
+ case 25:
1752
+ fallbackDocs = _q.sent();
1699
1753
  if (fallbackDocs.length) {
1700
1754
  documents = fallbackDocs;
1701
1755
  executedQuery = idLookup.query;
1702
1756
  fallbackMeta.idLookup.used = true;
1703
1757
  }
1704
- _h.label = 21;
1705
- case 21:
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:
1706
1867
  total = null;
1707
- if (!normalized.includeTotal) return [3 /*break*/, 23];
1868
+ if (!normalized.includeTotal) return [3 /*break*/, 48];
1708
1869
  return [4 /*yield*/, db.collection(collection).countDocuments(executedQuery, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
1709
- case 22:
1710
- total = _h.sent();
1711
- _h.label = 23;
1712
- case 23:
1870
+ case 47:
1871
+ total = _q.sent();
1872
+ _q.label = 48;
1873
+ case 48:
1713
1874
  sanitizedDocuments = isSuperAdmin
1714
1875
  ? documents
1715
1876
  : documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
1716
1877
  requestedFields = resolveProjectionRequestedFields(findOptions.projection);
1717
- if (!(sanitizedDocuments.length && requestedFields.length)) return [3 /*break*/, 27];
1878
+ if (!(sanitizedDocuments.length && requestedFields.length)) return [3 /*break*/, 52];
1718
1879
  missingFields = requestedFields.filter(function (field) { return !hasNonEmptyValue(sanitizedDocuments, field, { treatObjectLikeAsEmpty: true }); });
1719
- if (!missingFields.length) return [3 /*break*/, 27];
1720
- _e = probeDocs;
1721
- if (_e) return [3 /*break*/, 25];
1880
+ if (!missingFields.length) return [3 /*break*/, 52];
1881
+ _m = probeDocs;
1882
+ if (_m) return [3 /*break*/, 50];
1722
1883
  return [4 /*yield*/, fetchAssistantProbeDocs({
1723
1884
  db: db,
1724
1885
  collection: collection,
@@ -1727,26 +1888,26 @@ function executeAiAssistantMongoRead(payload, context) {
1727
1888
  isSuperAdmin: isSuperAdmin,
1728
1889
  includeClientScope: shouldScopeByClient
1729
1890
  })];
1730
- case 24:
1731
- _e = (_h.sent());
1732
- _h.label = 25;
1733
- case 25:
1734
- probeDocs = _e;
1735
- if (!probeDocs.length) return [3 /*break*/, 27];
1736
- projectionAliases = resolveFieldAliases(probeDocs, missingFields);
1737
- if (!Object.keys(projectionAliases).length) return [3 /*break*/, 27];
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];
1738
1899
  fallbackMeta.projectionAliases = {
1739
1900
  aliases: projectionAliases,
1740
1901
  attempted: true,
1741
1902
  used: false
1742
1903
  };
1743
1904
  expandedProjection = expandProjectionWithAliases(findOptions.projection, projectionAliases);
1744
- if (!(expandedProjection && expandedProjection !== findOptions.projection)) return [3 /*break*/, 27];
1905
+ if (!(expandedProjection && expandedProjection !== findOptions.projection)) return [3 /*break*/, 52];
1745
1906
  findOptions = __assign(__assign({}, findOptions), { projection: expandedProjection });
1746
1907
  normalized.findOptions.projection = expandedProjection;
1747
1908
  return [4 /*yield*/, db.collection(collection).find(executedQuery, findOptions).toArray()];
1748
- case 26:
1749
- refreshedDocs = _h.sent();
1909
+ case 51:
1910
+ refreshedDocs = _q.sent();
1750
1911
  if (refreshedDocs.length) {
1751
1912
  documents = refreshedDocs;
1752
1913
  sanitizedDocuments = isSuperAdmin
@@ -1754,13 +1915,30 @@ function executeAiAssistantMongoRead(payload, context) {
1754
1915
  : refreshedDocs.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
1755
1916
  fallbackMeta.projectionAliases.used = true;
1756
1917
  }
1757
- _h.label = 27;
1758
- case 27:
1759
- includeIds = ((_g = input.options) === null || _g === void 0 ? void 0 : _g.includeIds) === true;
1760
- fieldAliases = resolveFieldAliases(sanitizedDocuments, requestedFields);
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);
1761
1922
  displayDocs = Object.keys(fieldAliases).length
1762
1923
  ? applyFieldAliasesForDisplay(sanitizedDocuments, fieldAliases)
1763
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
+ }
1764
1942
  priorityFields = requestedFields.length
1765
1943
  ? __spreadArray(__spreadArray([], __read(requestedFields), false), __read(AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS), false) : AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS;
1766
1944
  display = buildDisplayTable(displayDocs, {
@@ -1797,10 +1975,10 @@ function executeAiAssistantMongoRead(payload, context) {
1797
1975
  }
1798
1976
  function executeAiAssistantMongoAggregate(payload, context) {
1799
1977
  return __awaiter(this, void 0, void 0, function () {
1800
- var input, rawCollection, dbName, db, collectionResolution, collection, _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, matchFields_1, _c, aliases, rewrittenPipeline, fallbackDocs, _loop_1, i, state_1, sanitizedDocuments, includeIds, display;
1801
- var _d, _e;
1802
- return __generator(this, function (_f) {
1803
- switch (_f.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) {
1804
1982
  case 0:
1805
1983
  input = payload || {};
1806
1984
  rawCollection = normalizeOptionalString(input.collection);
@@ -1811,15 +1989,16 @@ function executeAiAssistantMongoAggregate(payload, context) {
1811
1989
  db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
1812
1990
  return [4 /*yield*/, resolveAssistantCollectionName(db, dbName, rawCollection)];
1813
1991
  case 1:
1814
- collectionResolution = _f.sent();
1992
+ collectionResolution = _o.sent();
1815
1993
  collection = collectionResolution.name || rawCollection;
1994
+ schemaFields = getCollectionSchemaFieldNames(collection);
1816
1995
  return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
1817
1996
  case 2:
1818
- _a = _f.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
1997
+ _a = _o.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
1819
1998
  if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
1820
1999
  throw new Error('AI assistant mongo aggregate: Access denied.');
1821
2000
  }
1822
- customerId = normalizeOptionalString((_d = user === null || user === void 0 ? void 0 : user.other) === null || _d === void 0 ? void 0 : _d.id_customer);
2001
+ customerId = normalizeOptionalString((_l = user === null || user === void 0 ? void 0 : user.other) === null || _l === void 0 ? void 0 : _l.id_customer);
1823
2002
  fallbackMeta = {};
1824
2003
  baseQuery = normalizeMongoQuery(input.query);
1825
2004
  if (!isSuperAdmin && customerId) {
@@ -1844,11 +2023,11 @@ function executeAiAssistantMongoAggregate(payload, context) {
1844
2023
  if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 4];
1845
2024
  return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
1846
2025
  case 3:
1847
- _b = _f.sent();
2026
+ _b = _o.sent();
1848
2027
  return [3 /*break*/, 5];
1849
2028
  case 4:
1850
2029
  _b = false;
1851
- _f.label = 5;
2030
+ _o.label = 5;
1852
2031
  case 5:
1853
2032
  shouldScopeByClient = _b;
1854
2033
  clientScopedQuery = shouldScopeByClient
@@ -1878,7 +2057,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
1878
2057
  .aggregate(limitedPipeline, aggregateOptions)
1879
2058
  .toArray()];
1880
2059
  case 6:
1881
- documents = _f.sent();
2060
+ documents = _o.sent();
1882
2061
  executedPipeline = limitedPipeline;
1883
2062
  probeDocs = null;
1884
2063
  if (!(!documents.length && dateField)) return [3 /*break*/, 10];
@@ -1891,13 +2070,13 @@ function executeAiAssistantMongoAggregate(payload, context) {
1891
2070
  .aggregate(fallbackPipeline, aggregateOptions)
1892
2071
  .toArray()];
1893
2072
  case 7:
1894
- fallbackDocs = _f.sent();
2073
+ fallbackDocs = _o.sent();
1895
2074
  if (fallbackDocs.length) {
1896
2075
  documents = fallbackDocs;
1897
2076
  executedPipeline = fallbackPipeline;
1898
2077
  fallbackMeta.dateField.used = true;
1899
2078
  }
1900
- _f.label = 8;
2079
+ _o.label = 8;
1901
2080
  case 8:
1902
2081
  if (!(!documents.length && dateField !== 'createdAt')) return [3 /*break*/, 10];
1903
2082
  createdFallback = { from: dateField, to: 'createdAt', attempted: true, used: false };
@@ -1908,13 +2087,13 @@ function executeAiAssistantMongoAggregate(payload, context) {
1908
2087
  .aggregate(createdPipeline, aggregateOptions)
1909
2088
  .toArray()];
1910
2089
  case 9:
1911
- createdDocs = _f.sent();
2090
+ createdDocs = _o.sent();
1912
2091
  if (createdDocs.length) {
1913
2092
  documents = createdDocs;
1914
2093
  executedPipeline = createdPipeline;
1915
2094
  fallbackMeta.dateFieldCreatedAt.used = true;
1916
2095
  }
1917
- _f.label = 10;
2096
+ _o.label = 10;
1918
2097
  case 10:
1919
2098
  if (!!documents.length) return [3 /*break*/, 12];
1920
2099
  expanded = expandAggregateDateMatchFallback(executedPipeline);
@@ -1929,13 +2108,13 @@ function executeAiAssistantMongoAggregate(payload, context) {
1929
2108
  .aggregate(expanded.pipeline, aggregateOptions)
1930
2109
  .toArray()];
1931
2110
  case 11:
1932
- expandedDocs = _f.sent();
2111
+ expandedDocs = _o.sent();
1933
2112
  if (expandedDocs.length) {
1934
2113
  documents = expandedDocs;
1935
2114
  executedPipeline = expanded.pipeline;
1936
2115
  fallbackMeta.dateFieldsExpanded.used = true;
1937
2116
  }
1938
- _f.label = 12;
2117
+ _o.label = 12;
1939
2118
  case 12:
1940
2119
  if (!!documents.length) return [3 /*break*/, 16];
1941
2120
  completionFallback = resolveAggregateCompletionFallback(executedPipeline);
@@ -1954,13 +2133,13 @@ function executeAiAssistantMongoAggregate(payload, context) {
1954
2133
  .aggregate(fallbackPipeline, aggregateOptions)
1955
2134
  .toArray()];
1956
2135
  case 13:
1957
- fallbackDocs = _f.sent();
2136
+ fallbackDocs = _o.sent();
1958
2137
  if (fallbackDocs.length) {
1959
2138
  documents = fallbackDocs;
1960
2139
  executedPipeline = fallbackPipeline;
1961
2140
  fallbackMeta.completion.used = true;
1962
2141
  }
1963
- _f.label = 14;
2142
+ _o.label = 14;
1964
2143
  case 14:
1965
2144
  if (!!documents.length) return [3 /*break*/, 16];
1966
2145
  completionExprFallback = resolveAggregateCompletionExprFallback(executedPipeline);
@@ -1979,13 +2158,13 @@ function executeAiAssistantMongoAggregate(payload, context) {
1979
2158
  .aggregate(fallbackPipeline, aggregateOptions)
1980
2159
  .toArray()];
1981
2160
  case 15:
1982
- fallbackDocs = _f.sent();
2161
+ fallbackDocs = _o.sent();
1983
2162
  if (fallbackDocs.length) {
1984
2163
  documents = fallbackDocs;
1985
2164
  executedPipeline = fallbackPipeline;
1986
2165
  fallbackMeta.completion.used = true;
1987
2166
  }
1988
- _f.label = 16;
2167
+ _o.label = 16;
1989
2168
  case 16:
1990
2169
  if (!(documents.length <= 1)) return [3 /*break*/, 18];
1991
2170
  unwindFallback = resolveAggregateUnwindFallback(executedPipeline);
@@ -1997,13 +2176,13 @@ function executeAiAssistantMongoAggregate(payload, context) {
1997
2176
  .aggregate(fallbackPipeline, aggregateOptions)
1998
2177
  .toArray()];
1999
2178
  case 17:
2000
- fallbackDocs = _f.sent();
2179
+ fallbackDocs = _o.sent();
2001
2180
  if (fallbackDocs.length > documents.length) {
2002
2181
  documents = fallbackDocs;
2003
2182
  executedPipeline = fallbackPipeline;
2004
2183
  fallbackMeta.unwind.used = true;
2005
2184
  }
2006
- _f.label = 18;
2185
+ _o.label = 18;
2007
2186
  case 18:
2008
2187
  if (!!documents.length) return [3 /*break*/, 20];
2009
2188
  nameFallback = resolveAggregateNameMatchFallback(executedPipeline);
@@ -2020,15 +2199,87 @@ function executeAiAssistantMongoAggregate(payload, context) {
2020
2199
  .aggregate(fallbackPipeline, aggregateOptions)
2021
2200
  .toArray()];
2022
2201
  case 19:
2023
- fallbackDocs = _f.sent();
2202
+ fallbackDocs = _o.sent();
2024
2203
  if (fallbackDocs.length) {
2025
2204
  documents = fallbackDocs;
2026
2205
  executedPipeline = fallbackPipeline;
2027
2206
  fallbackMeta.nameMatch.used = true;
2028
2207
  }
2029
- _f.label = 20;
2208
+ _o.label = 20;
2030
2209
  case 20:
2031
- if (!!documents.length) return [3 /*break*/, 24];
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];
2032
2283
  matchFields_1 = new Set();
2033
2284
  (executedPipeline || []).forEach(function (stage) {
2034
2285
  if (stage && typeof stage === 'object' && stage.$match && typeof stage.$match === 'object') {
@@ -2037,9 +2288,9 @@ function executeAiAssistantMongoAggregate(payload, context) {
2037
2288
  .forEach(function (field) { return matchFields_1.add(field); });
2038
2289
  }
2039
2290
  });
2040
- if (!matchFields_1.size) return [3 /*break*/, 24];
2041
- _c = probeDocs;
2042
- if (_c) return [3 /*break*/, 22];
2291
+ if (!matchFields_1.size) return [3 /*break*/, 30];
2292
+ _d = probeDocs;
2293
+ if (_d) return [3 /*break*/, 28];
2043
2294
  return [4 /*yield*/, fetchAssistantProbeDocs({
2044
2295
  db: db,
2045
2296
  collection: collection,
@@ -2048,14 +2299,14 @@ function executeAiAssistantMongoAggregate(payload, context) {
2048
2299
  isSuperAdmin: isSuperAdmin,
2049
2300
  includeClientScope: shouldScopeByClient
2050
2301
  })];
2051
- case 21:
2052
- _c = (_f.sent());
2053
- _f.label = 22;
2054
- case 22:
2055
- probeDocs = _c;
2056
- if (!probeDocs.length) return [3 /*break*/, 24];
2057
- aliases = resolveFieldAliases(probeDocs, Array.from(matchFields_1));
2058
- if (!Object.keys(aliases).length) return [3 /*break*/, 24];
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];
2059
2310
  fallbackMeta.queryFieldAliases = {
2060
2311
  aliases: aliases,
2061
2312
  attempted: true,
@@ -2066,31 +2317,31 @@ function executeAiAssistantMongoAggregate(payload, context) {
2066
2317
  var _b = __read(_a, 2), from = _b[0], to = _b[1];
2067
2318
  return replaceFieldPathDeep(acc, from, to);
2068
2319
  }, executedPipeline);
2069
- if (!!containsForbiddenMongoOperators(rewrittenPipeline)) return [3 /*break*/, 24];
2320
+ if (!!containsForbiddenMongoOperators(rewrittenPipeline)) return [3 /*break*/, 30];
2070
2321
  return [4 /*yield*/, db.collection(collection)
2071
2322
  .aggregate(rewrittenPipeline, aggregateOptions)
2072
2323
  .toArray()];
2073
- case 23:
2074
- fallbackDocs = _f.sent();
2324
+ case 29:
2325
+ fallbackDocs = _o.sent();
2075
2326
  if (fallbackDocs.length) {
2076
2327
  documents = fallbackDocs;
2077
2328
  executedPipeline = rewrittenPipeline;
2078
2329
  fallbackMeta.queryFieldAliases.used = true;
2079
2330
  }
2080
- _f.label = 24;
2081
- case 24:
2082
- if (!!documents.length) return [3 /*break*/, 28];
2083
- _loop_1 = function (i) {
2084
- var stage, _g, idLookup, rewrittenPipeline, fallbackDocs;
2085
- return __generator(this, function (_h) {
2086
- switch (_h.label) {
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) {
2087
2338
  case 0:
2088
2339
  stage = executedPipeline[i];
2089
2340
  if (!stage || typeof stage !== 'object' || !stage.$match || typeof stage.$match !== 'object') {
2090
2341
  return [2 /*return*/, "continue"];
2091
2342
  }
2092
- _g = probeDocs;
2093
- if (_g) return [3 /*break*/, 2];
2343
+ _q = probeDocs;
2344
+ if (_q) return [3 /*break*/, 2];
2094
2345
  return [4 /*yield*/, fetchAssistantProbeDocs({
2095
2346
  db: db,
2096
2347
  collection: collection,
@@ -2100,10 +2351,10 @@ function executeAiAssistantMongoAggregate(payload, context) {
2100
2351
  includeClientScope: shouldScopeByClient
2101
2352
  })];
2102
2353
  case 1:
2103
- _g = (_h.sent());
2104
- _h.label = 2;
2354
+ _q = (_r.sent());
2355
+ _r.label = 2;
2105
2356
  case 2:
2106
- probeDocs = _g;
2357
+ probeDocs = _q;
2107
2358
  return [4 /*yield*/, applyIdLookupFallbackToQuery({
2108
2359
  query: stage.$match,
2109
2360
  db: db,
@@ -2114,7 +2365,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
2114
2365
  probeDocs: probeDocs || undefined
2115
2366
  })];
2116
2367
  case 3:
2117
- idLookup = _h.sent();
2368
+ idLookup = _r.sent();
2118
2369
  if (!idLookup) {
2119
2370
  return [2 /*return*/, "continue"];
2120
2371
  }
@@ -2125,37 +2376,164 @@ function executeAiAssistantMongoAggregate(payload, context) {
2125
2376
  .aggregate(rewrittenPipeline, aggregateOptions)
2126
2377
  .toArray()];
2127
2378
  case 4:
2128
- fallbackDocs = _h.sent();
2379
+ fallbackDocs = _r.sent();
2129
2380
  if (fallbackDocs.length) {
2130
2381
  documents = fallbackDocs;
2131
2382
  executedPipeline = rewrittenPipeline;
2132
2383
  fallbackMeta.idLookup.used = true;
2133
2384
  return [2 /*return*/, "break"];
2134
2385
  }
2135
- _h.label = 5;
2386
+ _r.label = 5;
2136
2387
  case 5: return [2 /*return*/];
2137
2388
  }
2138
2389
  });
2139
2390
  };
2140
2391
  i = 0;
2141
- _f.label = 25;
2142
- case 25:
2143
- if (!(i < (executedPipeline || []).length)) return [3 /*break*/, 28];
2144
- return [5 /*yield**/, _loop_1(i)];
2145
- case 26:
2146
- state_1 = _f.sent();
2147
- if (state_1 === "break")
2148
- return [3 /*break*/, 28];
2149
- _f.label = 27;
2150
- case 27:
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:
2151
2402
  i += 1;
2152
- return [3 /*break*/, 25];
2153
- case 28:
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:
2154
2514
  sanitizedDocuments = isSuperAdmin
2155
2515
  ? documents
2156
2516
  : documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
2157
- includeIds = ((_e = input.options) === null || _e === void 0 ? void 0 : _e.includeIds) === true;
2158
- 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, {
2159
2537
  includeIds: includeIds,
2160
2538
  maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
2161
2539
  maxRows: normalizedOptions.limit || sanitizedDocuments.length,
@@ -2329,7 +2707,7 @@ function buildAssistantToolFallbackResponse(result) {
2329
2707
  return lines.join('\n').trim();
2330
2708
  }
2331
2709
  function buildAssistantDebugPayload(params) {
2332
- 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;
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;
2333
2711
  var notes = [];
2334
2712
  if (params.dataQuestion) {
2335
2713
  notes.push('Detected a data request; tool call required.');
@@ -2426,15 +2804,34 @@ function buildAssistantDebugPayload(params) {
2426
2804
  : fallbackInfo.nameMatch.field;
2427
2805
  notes.push("Expanded name match fields: ".concat(fields, "."));
2428
2806
  }
2429
- if ((_t = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.idLookup) === null || _t === void 0 ? void 0 : _t.used) {
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) {
2430
2817
  var field = fallbackInfo.idLookup.field || 'id';
2431
2818
  var strategy = fallbackInfo.idLookup.strategy || 'lookup';
2432
2819
  var collection = fallbackInfo.idLookup.collection ? " in ".concat(fallbackInfo.idLookup.collection) : '';
2433
2820
  var detail = fallbackInfo.idLookup.nameField ? " via ".concat(fallbackInfo.idLookup.nameField) : '';
2434
2821
  notes.push("Resolved ".concat(field, " by ").concat(strategy).concat(collection).concat(detail, "."));
2435
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
+ }
2436
2833
  if (params.toolError) {
2437
- var errorMessage = ((_u = params.toolError) === null || _u === void 0 ? void 0 : _u.message) || String(params.toolError || '');
2834
+ var errorMessage = ((_x = params.toolError) === null || _x === void 0 ? void 0 : _x.message) || String(params.toolError || '');
2438
2835
  if (errorMessage) {
2439
2836
  notes.push("Tool error: ".concat(errorMessage));
2440
2837
  }
@@ -2455,13 +2852,13 @@ function buildAssistantDebugPayload(params) {
2455
2852
  collectionResolved: resolvedCollection || undefined,
2456
2853
  collectionMatched: matchedCollection,
2457
2854
  collectionCandidates: candidateCollections.length ? candidateCollections : undefined,
2458
- collectionScore: typeof ((_v = params.toolResponseDebug) === null || _v === void 0 ? void 0 : _v.collectionScore) === 'number'
2855
+ collectionScore: typeof ((_y = params.toolResponseDebug) === null || _y === void 0 ? void 0 : _y.collectionScore) === 'number'
2459
2856
  ? params.toolResponseDebug.collectionScore
2460
2857
  : undefined,
2461
- query: ((_w = params.toolResponseDebug) === null || _w === void 0 ? void 0 : _w.query) || undefined,
2462
- pipeline: ((_x = params.toolResponseDebug) === null || _x === void 0 ? void 0 : _x.executedPipeline) || ((_y = params.toolResponseDebug) === null || _y === void 0 ? void 0 : _y.originalPipeline) || undefined,
2463
- options: ((_z = params.toolResponseDebug) === null || _z === void 0 ? void 0 : _z.options) || undefined,
2464
- fallbacks: ((_0 = params.toolResponseDebug) === null || _0 === void 0 ? void 0 : _0.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,
2465
2862
  notes: notes
2466
2863
  };
2467
2864
  if (params.trace && typeof params.trace === 'object') {
@@ -2728,6 +3125,93 @@ function tokenizeFieldKey(value) {
2728
3125
  function normalizeFieldMatchKey(value) {
2729
3126
  return tokenizeFieldKey(value).join('');
2730
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
+ }
2731
3215
  function expandFieldTokens(tokens) {
2732
3216
  var expanded = new Set();
2733
3217
  tokens.forEach(function (token) {
@@ -2897,15 +3381,406 @@ function normalizeIdsForTargetField(ids, targetDocs, targetFieldPath, targetFiel
2897
3381
  });
2898
3382
  return normalized;
2899
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
+ }
2900
3775
  function hasNonEmptyValue(docs, fieldPath, options) {
2901
- var e_3, _a;
3776
+ var e_9, _a;
2902
3777
  if (!Array.isArray(docs) || !fieldPath) {
2903
3778
  return false;
2904
3779
  }
2905
3780
  var usePath = fieldPath.includes('.');
2906
3781
  try {
2907
- for (var docs_2 = __values(docs), docs_2_1 = docs_2.next(); !docs_2_1.done; docs_2_1 = docs_2.next()) {
2908
- var doc = docs_2_1.value;
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;
2909
3784
  var value = usePath ? getValueAtPath(doc, fieldPath) : doc === null || doc === void 0 ? void 0 : doc[fieldPath];
2910
3785
  if ((options === null || options === void 0 ? void 0 : options.treatObjectLikeAsEmpty) && isDisplayObjectLike(value)) {
2911
3786
  continue;
@@ -2915,12 +3790,12 @@ function hasNonEmptyValue(docs, fieldPath, options) {
2915
3790
  }
2916
3791
  }
2917
3792
  }
2918
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
3793
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
2919
3794
  finally {
2920
3795
  try {
2921
- if (docs_2_1 && !docs_2_1.done && (_a = docs_2.return)) _a.call(docs_2);
3796
+ if (docs_3_1 && !docs_3_1.done && (_a = docs_3.return)) _a.call(docs_3);
2922
3797
  }
2923
- finally { if (e_3) throw e_3.error; }
3798
+ finally { if (e_9) throw e_9.error; }
2924
3799
  }
2925
3800
  return false;
2926
3801
  }
@@ -2980,7 +3855,7 @@ function collectFieldCandidates(docs) {
2980
3855
  });
2981
3856
  return candidates;
2982
3857
  }
2983
- function resolveFieldAliases(docs, requestedFields) {
3858
+ function resolveFieldAliases(docs, requestedFields, schemaFields) {
2984
3859
  var aliases = {};
2985
3860
  if (!Array.isArray(docs) || !requestedFields.length) {
2986
3861
  return aliases;
@@ -2990,11 +3865,24 @@ function resolveFieldAliases(docs, requestedFields) {
2990
3865
  return aliases;
2991
3866
  }
2992
3867
  var candidates = collectFieldCandidates(docs);
3868
+ var schemaFieldList = Array.isArray(schemaFields) ? schemaFields.filter(Boolean) : [];
3869
+ var candidateFieldList = schemaFieldList.length ? schemaFieldList : Array.from(candidates.keys());
2993
3870
  missing.forEach(function (field) {
2994
3871
  var normalizedRequested = normalizeFieldMatchKey(field);
2995
3872
  if (!normalizedRequested) {
2996
3873
  return;
2997
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;
2998
3886
  var bestPath = '';
2999
3887
  var bestScore = 0;
3000
3888
  candidates.forEach(function (stats, path) {
@@ -3004,6 +3892,13 @@ function resolveFieldAliases(docs, requestedFields) {
3004
3892
  if (isAssistantIdField(path)) {
3005
3893
  return;
3006
3894
  }
3895
+ var candidateTokens = tokenizeFieldKey(path);
3896
+ if (isUnsafeFieldAlias(requestedBaseTokens, candidateTokens)) {
3897
+ return;
3898
+ }
3899
+ if (!requestedHasType && candidateTokens.includes('type') && hasNonTypeCandidate) {
3900
+ return;
3901
+ }
3007
3902
  var normalizedCandidate = stats.normalized || normalizeFieldMatchKey(path);
3008
3903
  if (!normalizedCandidate) {
3009
3904
  return;
@@ -3016,11 +3911,9 @@ function resolveFieldAliases(docs, requestedFields) {
3016
3911
  score = 70;
3017
3912
  }
3018
3913
  else {
3019
- var candidateTokens_1 = tokenizeFieldKey(path);
3020
- var requestedBaseTokens = tokenizeFieldKey(field);
3021
3914
  var requestedTokens = expandFieldTokens(requestedBaseTokens);
3022
- var overlap = requestedTokens.filter(function (token) { return candidateTokens_1.includes(token); }).length;
3023
- var baseOverlap = requestedBaseTokens.filter(function (token) { return candidateTokens_1.includes(token); }).length;
3915
+ var overlap = requestedTokens.filter(function (token) { return candidateTokens.includes(token); }).length;
3916
+ var baseOverlap = requestedBaseTokens.filter(function (token) { return candidateTokens.includes(token); }).length;
3024
3917
  if (overlap > 0) {
3025
3918
  score = 40 + overlap * 10;
3026
3919
  if (baseOverlap === 0) {
@@ -3744,7 +4637,7 @@ function matchContainsField(value, field) {
3744
4637
  });
3745
4638
  }
3746
4639
  function resolveAggregateCompletionFallback(pipeline) {
3747
- var e_4, _a;
4640
+ var e_10, _a;
3748
4641
  if (!Array.isArray(pipeline)) {
3749
4642
  return null;
3750
4643
  }
@@ -3757,7 +4650,7 @@ function resolveAggregateCompletionFallback(pipeline) {
3757
4650
  }
3758
4651
  var addFields = stage.$addFields;
3759
4652
  try {
3760
- for (var _b = (e_4 = 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()) {
3761
4654
  var key = _c.value;
3762
4655
  if (!isCompletionFieldName(key)) {
3763
4656
  continue;
@@ -3771,12 +4664,12 @@ function resolveAggregateCompletionFallback(pipeline) {
3771
4664
  }
3772
4665
  }
3773
4666
  }
3774
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
4667
+ catch (e_10_1) { e_10 = { error: e_10_1 }; }
3775
4668
  finally {
3776
4669
  try {
3777
4670
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3778
4671
  }
3779
- finally { if (e_4) throw e_4.error; }
4672
+ finally { if (e_10) throw e_10.error; }
3780
4673
  }
3781
4674
  if (candidateField) {
3782
4675
  break;
@@ -3932,7 +4825,7 @@ function buildCompletionFallbackSources(field) {
3932
4825
  ]);
3933
4826
  }
3934
4827
  function resolveAggregateCompletionExprFallback(pipeline) {
3935
- var e_5, _a;
4828
+ var e_11, _a;
3936
4829
  if (!Array.isArray(pipeline)) {
3937
4830
  return null;
3938
4831
  }
@@ -3952,7 +4845,7 @@ function resolveAggregateCompletionExprFallback(pipeline) {
3952
4845
  }
3953
4846
  if (!candidateField) {
3954
4847
  try {
3955
- for (var _b = (e_5 = 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()) {
3956
4849
  var key = _c.value;
3957
4850
  if (key.startsWith('$')) {
3958
4851
  continue;
@@ -3967,12 +4860,12 @@ function resolveAggregateCompletionExprFallback(pipeline) {
3967
4860
  }
3968
4861
  }
3969
4862
  }
3970
- catch (e_5_1) { e_5 = { error: e_5_1 }; }
4863
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
3971
4864
  finally {
3972
4865
  try {
3973
4866
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3974
4867
  }
3975
- finally { if (e_5) throw e_5.error; }
4868
+ finally { if (e_11) throw e_11.error; }
3976
4869
  }
3977
4870
  }
3978
4871
  if (!candidateField) {
@@ -4142,7 +5035,7 @@ function isRegexMatchCondition(value) {
4142
5035
  return false;
4143
5036
  }
4144
5037
  function findRegexMatchInMatchObject(match, prefix) {
4145
- var e_6, _a, e_7, _b;
5038
+ var e_12, _a, e_13, _b;
4146
5039
  if (prefix === void 0) { prefix = ''; }
4147
5040
  if (Array.isArray(match)) {
4148
5041
  try {
@@ -4154,12 +5047,12 @@ function findRegexMatchInMatchObject(match, prefix) {
4154
5047
  }
4155
5048
  }
4156
5049
  }
4157
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
5050
+ catch (e_12_1) { e_12 = { error: e_12_1 }; }
4158
5051
  finally {
4159
5052
  try {
4160
5053
  if (match_1_1 && !match_1_1.done && (_a = match_1.return)) _a.call(match_1);
4161
5054
  }
4162
- finally { if (e_6) throw e_6.error; }
5055
+ finally { if (e_12) throw e_12.error; }
4163
5056
  }
4164
5057
  return null;
4165
5058
  }
@@ -4168,8 +5061,8 @@ function findRegexMatchInMatchObject(match, prefix) {
4168
5061
  }
4169
5062
  var keys = Object.keys(match);
4170
5063
  try {
4171
- for (var keys_1 = __values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
4172
- 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;
4173
5066
  var value = match[key];
4174
5067
  if (key.startsWith('$')) {
4175
5068
  var found = findRegexMatchInMatchObject(value, prefix);
@@ -4190,12 +5083,12 @@ function findRegexMatchInMatchObject(match, prefix) {
4190
5083
  }
4191
5084
  }
4192
5085
  }
4193
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
5086
+ catch (e_13_1) { e_13 = { error: e_13_1 }; }
4194
5087
  finally {
4195
5088
  try {
4196
- 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);
4197
5090
  }
4198
- finally { if (e_7) throw e_7.error; }
5091
+ finally { if (e_13) throw e_13.error; }
4199
5092
  }
4200
5093
  return null;
4201
5094
  }
@@ -4384,6 +5277,173 @@ function stripMatchField(match, field) {
4384
5277
  });
4385
5278
  return result;
4386
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
+ }
4387
5447
  function isEmptyQueryValue(value) {
4388
5448
  if (value === null || value === undefined) {
4389
5449
  return true;
@@ -4579,6 +5639,155 @@ function buildIdFieldNameFallbackQuery(query, idField, nameField, condition) {
4579
5639
  : { $and: [baseMatch, { $or: orConditions }] };
4580
5640
  return nextMatch;
4581
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
+ }
4582
5791
  function resolveIdLookupCandidates(baseToken, collectionNames) {
4583
5792
  var normalizedBase = normalizeOptionalString(baseToken).toLowerCase();
4584
5793
  if (!normalizedBase || !Array.isArray(collectionNames) || !collectionNames.length) {
@@ -4666,8 +5875,8 @@ function lookupIdsForNameMatch(params) {
4666
5875
  }
4667
5876
  function applyIdLookupFallbackToQuery(params) {
4668
5877
  return __awaiter(this, void 0, void 0, function () {
4669
- var query, db, dbName, idClient, idCustomer, isSuperAdmin, probeDocs, conditions, collectionNames, _a, conditions_1, conditions_1_1, condition, regex, baseToken, targetFieldType, nextValue, localNameField, candidates, candidates_1, candidates_1_1, candidate, candidateHasClientScope, _b, candidateProbe, lookup, targetFieldType, normalizedIds, idsForQuery, e_8_1, e_9_1;
4670
- var e_9, _c, e_8, _d;
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;
4671
5880
  var _e;
4672
5881
  return __generator(this, function (_f) {
4673
5882
  switch (_f.label) {
@@ -4737,11 +5946,11 @@ function applyIdLookupFallbackToQuery(params) {
4737
5946
  _f.label = 5;
4738
5947
  case 5:
4739
5948
  _f.trys.push([5, 14, 15, 16]);
4740
- candidates_1 = (e_8 = void 0, __values(candidates)), candidates_1_1 = candidates_1.next();
5949
+ candidates_3 = (e_19 = void 0, __values(candidates)), candidates_3_1 = candidates_3.next();
4741
5950
  _f.label = 6;
4742
5951
  case 6:
4743
- if (!!candidates_1_1.done) return [3 /*break*/, 13];
4744
- candidate = candidates_1_1.value;
5952
+ if (!!candidates_3_1.done) return [3 /*break*/, 13];
5953
+ candidate = candidates_3_1.value;
4745
5954
  if (!candidate) {
4746
5955
  return [3 /*break*/, 12];
4747
5956
  }
@@ -4800,32 +6009,32 @@ function applyIdLookupFallbackToQuery(params) {
4800
6009
  }
4801
6010
  _f.label = 12;
4802
6011
  case 12:
4803
- candidates_1_1 = candidates_1.next();
6012
+ candidates_3_1 = candidates_3.next();
4804
6013
  return [3 /*break*/, 6];
4805
6014
  case 13: return [3 /*break*/, 16];
4806
6015
  case 14:
4807
- e_8_1 = _f.sent();
4808
- e_8 = { error: e_8_1 };
6016
+ e_19_1 = _f.sent();
6017
+ e_19 = { error: e_19_1 };
4809
6018
  return [3 /*break*/, 16];
4810
6019
  case 15:
4811
6020
  try {
4812
- if (candidates_1_1 && !candidates_1_1.done && (_d = candidates_1.return)) _d.call(candidates_1);
6021
+ if (candidates_3_1 && !candidates_3_1.done && (_d = candidates_3.return)) _d.call(candidates_3);
4813
6022
  }
4814
- finally { if (e_8) throw e_8.error; }
6023
+ finally { if (e_19) throw e_19.error; }
4815
6024
  return [7 /*endfinally*/];
4816
6025
  case 16:
4817
6026
  conditions_1_1 = conditions_1.next();
4818
6027
  return [3 /*break*/, 4];
4819
6028
  case 17: return [3 /*break*/, 20];
4820
6029
  case 18:
4821
- e_9_1 = _f.sent();
4822
- e_9 = { error: e_9_1 };
6030
+ e_20_1 = _f.sent();
6031
+ e_20 = { error: e_20_1 };
4823
6032
  return [3 /*break*/, 20];
4824
6033
  case 19:
4825
6034
  try {
4826
6035
  if (conditions_1_1 && !conditions_1_1.done && (_c = conditions_1.return)) _c.call(conditions_1);
4827
6036
  }
4828
- finally { if (e_9) throw e_9.error; }
6037
+ finally { if (e_20) throw e_20.error; }
4829
6038
  return [7 /*endfinally*/];
4830
6039
  case 20: return [2 /*return*/, null];
4831
6040
  }
@@ -4964,6 +6173,14 @@ function shouldApplyAssistantNameRegex(field) {
4964
6173
  function escapeRegexValue(value) {
4965
6174
  return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
4966
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
+ }
4967
6184
  function applyAssistantNameRegexToQuery(query) {
4968
6185
  if (Array.isArray(query)) {
4969
6186
  return query.map(function (entry) { return applyAssistantNameRegexToQuery(entry); });
@@ -4980,7 +6197,7 @@ function applyAssistantNameRegexToQuery(query) {
4980
6197
  }
4981
6198
  if (typeof value === 'string' && shouldApplyAssistantNameRegex(key)) {
4982
6199
  var trimmed = value.trim();
4983
- result[key] = trimmed ? new RegExp(escapeRegexValue(trimmed), 'i') : value;
6200
+ result[key] = trimmed ? buildTokenizedRegex(trimmed) : value;
4984
6201
  return;
4985
6202
  }
4986
6203
  if (value && typeof value === 'object') {
@@ -5007,12 +6224,13 @@ function hasOperatorKeys(value) {
5007
6224
  return Object.keys(value).some(function (key) { return key.startsWith('$'); });
5008
6225
  }
5009
6226
  function rewriteEmbeddedMatchObjects(query) {
5010
- var rewriteValue = function (value, allowArrayRewrite) {
6227
+ var rewriteValue = function (value, allowArrayRewrite, inOperator) {
6228
+ if (inOperator === void 0) { inOperator = false; }
5011
6229
  if (Array.isArray(value)) {
5012
6230
  if (!allowArrayRewrite) {
5013
6231
  return value;
5014
6232
  }
5015
- return value.map(function (entry) { return rewriteValue(entry, true); });
6233
+ return value.map(function (entry) { return rewriteValue(entry, true, inOperator); });
5016
6234
  }
5017
6235
  if (!value || typeof value !== 'object' || value instanceof Date || value instanceof RegExp || isMongoObjectId(value)) {
5018
6236
  return value;
@@ -5021,38 +6239,38 @@ function rewriteEmbeddedMatchObjects(query) {
5021
6239
  Object.keys(value).forEach(function (key) {
5022
6240
  var entry = value[key];
5023
6241
  if (key.startsWith('$')) {
5024
- result[key] = rewriteValue(entry, true);
6242
+ result[key] = rewriteValue(entry, true, true);
5025
6243
  return;
5026
6244
  }
5027
- if (isPlainMatchObject(entry) && !Array.isArray(entry) && !hasOperatorKeys(entry)) {
5028
- var flattened = flattenMatchObject(entry, key);
6245
+ if (!inOperator && isPlainMatchObject(entry) && !Array.isArray(entry) && !hasOperatorKeys(entry)) {
6246
+ var flattened = flattenMatchObject(entry, key, inOperator);
5029
6247
  Object.assign(result, flattened);
5030
6248
  return;
5031
6249
  }
5032
6250
  if (isPlainMatchObject(entry) && !Array.isArray(entry)) {
5033
- result[key] = rewriteValue(entry, true);
6251
+ result[key] = rewriteValue(entry, true, inOperator);
5034
6252
  return;
5035
6253
  }
5036
6254
  if (Array.isArray(entry)) {
5037
- result[key] = allowArrayRewrite ? entry.map(function (item) { return rewriteValue(item, true); }) : entry;
6255
+ result[key] = allowArrayRewrite ? entry.map(function (item) { return rewriteValue(item, true, inOperator); }) : entry;
5038
6256
  return;
5039
6257
  }
5040
6258
  result[key] = entry;
5041
6259
  });
5042
6260
  return result;
5043
6261
  };
5044
- var flattenMatchObject = function (value, prefix) {
6262
+ var flattenMatchObject = function (value, prefix, inOperator) {
5045
6263
  var result = {};
5046
6264
  Object.keys(value || {}).forEach(function (key) {
5047
6265
  var entry = value[key];
5048
6266
  var currentPath = "".concat(prefix, ".").concat(key);
5049
6267
  if (isPlainMatchObject(entry) && !Array.isArray(entry) && !hasOperatorKeys(entry)) {
5050
- var flattened = flattenMatchObject(entry, currentPath);
6268
+ var flattened = flattenMatchObject(entry, currentPath, inOperator);
5051
6269
  Object.assign(result, flattened);
5052
6270
  return;
5053
6271
  }
5054
6272
  if (isPlainMatchObject(entry) && !Array.isArray(entry)) {
5055
- result[currentPath] = rewriteValue(entry, true);
6273
+ result[currentPath] = rewriteValue(entry, true, inOperator);
5056
6274
  return;
5057
6275
  }
5058
6276
  if (Array.isArray(entry)) {
@@ -5234,6 +6452,9 @@ function scoreCollectionMatch(requestedTokens, candidateName, tokenWeights) {
5234
6452
  else if (requestedKey && (candidateKey.includes(requestedKey) || requestedKey.includes(candidateKey))) {
5235
6453
  score += 20;
5236
6454
  }
6455
+ if (isVersionCollectionName(candidateName)) {
6456
+ score -= 15;
6457
+ }
5237
6458
  return score;
5238
6459
  }
5239
6460
  function scoreCollectionMatchDetailed(requestedTokens, candidateName, tokenWeights) {
@@ -5253,6 +6474,9 @@ function scoreCollectionMatchDetailed(requestedTokens, candidateName, tokenWeigh
5253
6474
  score += 20;
5254
6475
  keyMatch = 'partial';
5255
6476
  }
6477
+ if (isVersionCollectionName(candidateName)) {
6478
+ score -= 15;
6479
+ }
5256
6480
  return {
5257
6481
  score: score,
5258
6482
  tokenMatches: tokenMatches,
@@ -5326,6 +6550,115 @@ function isVersionCollectionName(value) {
5326
6550
  var normalized = normalizeOptionalString(value).toLowerCase();
5327
6551
  return normalized.endsWith('.versions') || normalized.endsWith('-versions') || normalized.includes('.versions.');
5328
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
+ }
5329
6662
  function pickPreferredCollectionCandidate(ranked) {
5330
6663
  if (!Array.isArray(ranked) || !ranked.length) {
5331
6664
  return null;
@@ -5430,7 +6763,7 @@ function resolveAssistantCollectionName(db, dbName, requested) {
5430
6763
  });
5431
6764
  }
5432
6765
  function findQueryDateField(query) {
5433
- var e_10, _a, e_11, _b;
6766
+ var e_21, _a, e_22, _b;
5434
6767
  if (!query || typeof query !== 'object') {
5435
6768
  return null;
5436
6769
  }
@@ -5444,12 +6777,12 @@ function findQueryDateField(query) {
5444
6777
  }
5445
6778
  }
5446
6779
  }
5447
- catch (e_10_1) { e_10 = { error: e_10_1 }; }
6780
+ catch (e_21_1) { e_21 = { error: e_21_1 }; }
5448
6781
  finally {
5449
6782
  try {
5450
6783
  if (query_1_1 && !query_1_1.done && (_a = query_1.return)) _a.call(query_1);
5451
6784
  }
5452
- finally { if (e_10) throw e_10.error; }
6785
+ finally { if (e_21) throw e_21.error; }
5453
6786
  }
5454
6787
  return null;
5455
6788
  }
@@ -5468,12 +6801,12 @@ function findQueryDateField(query) {
5468
6801
  }
5469
6802
  }
5470
6803
  }
5471
- catch (e_11_1) { e_11 = { error: e_11_1 }; }
6804
+ catch (e_22_1) { e_22 = { error: e_22_1 }; }
5472
6805
  finally {
5473
6806
  try {
5474
6807
  if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
5475
6808
  }
5476
- finally { if (e_11) throw e_11.error; }
6809
+ finally { if (e_22) throw e_22.error; }
5477
6810
  }
5478
6811
  return null;
5479
6812
  }
@@ -5629,7 +6962,7 @@ function expandAggregateDateMatchFallback(pipeline) {
5629
6962
  if (!Array.isArray(pipeline)) {
5630
6963
  return null;
5631
6964
  }
5632
- var _loop_2 = function (i) {
6965
+ var _loop_7 = function (i) {
5633
6966
  var stage = pipeline[i];
5634
6967
  if (!stage || typeof stage !== 'object' || !stage.$match || typeof stage.$match !== 'object') {
5635
6968
  return "continue";
@@ -5677,9 +7010,9 @@ function expandAggregateDateMatchFallback(pipeline) {
5677
7010
  return { value: { pipeline: updated, fields: Array.from(addedFields) } };
5678
7011
  };
5679
7012
  for (var i = 0; i < pipeline.length; i += 1) {
5680
- var state_2 = _loop_2(i);
5681
- if (typeof state_2 === "object")
5682
- return state_2.value;
7013
+ var state_5 = _loop_7(i);
7014
+ if (typeof state_5 === "object")
7015
+ return state_5.value;
5683
7016
  }
5684
7017
  return null;
5685
7018
  }
@@ -5695,7 +7028,7 @@ function resolveQueryDateFieldFallback(query) {
5695
7028
  return { from: dateField, to: fallback };
5696
7029
  }
5697
7030
  function containsForbiddenMongoOperators(value) {
5698
- var e_12, _a;
7031
+ var e_23, _a;
5699
7032
  if (!value || typeof value !== 'object') {
5700
7033
  return false;
5701
7034
  }
@@ -5714,12 +7047,12 @@ function containsForbiddenMongoOperators(value) {
5714
7047
  }
5715
7048
  }
5716
7049
  }
5717
- catch (e_12_1) { e_12 = { error: e_12_1 }; }
7050
+ catch (e_23_1) { e_23 = { error: e_23_1 }; }
5718
7051
  finally {
5719
7052
  try {
5720
7053
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
5721
7054
  }
5722
- finally { if (e_12) throw e_12.error; }
7055
+ finally { if (e_23) throw e_23.error; }
5723
7056
  }
5724
7057
  return false;
5725
7058
  }
@@ -6010,8 +7343,8 @@ function applyCodexStreamStatusHandler(runOptions, streamStatusHandler) {
6010
7343
  }
6011
7344
  function waitForCodexWorkerMessage(worker, streamStatusHandler) {
6012
7345
  return __awaiter(this, void 0, void 0, function () {
6013
- var _a, _b, _c, _d, message, payload, status_1, e_13_1;
6014
- var _e, e_13, _f, _g;
7346
+ var _a, _b, _c, _d, message, payload, status_1, e_24_1;
7347
+ var _e, e_24, _f, _g;
6015
7348
  return __generator(this, function (_h) {
6016
7349
  switch (_h.label) {
6017
7350
  case 0:
@@ -6038,8 +7371,8 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
6038
7371
  return [3 /*break*/, 1];
6039
7372
  case 4: return [3 /*break*/, 11];
6040
7373
  case 5:
6041
- e_13_1 = _h.sent();
6042
- e_13 = { error: e_13_1 };
7374
+ e_24_1 = _h.sent();
7375
+ e_24 = { error: e_24_1 };
6043
7376
  return [3 /*break*/, 11];
6044
7377
  case 6:
6045
7378
  _h.trys.push([6, , 9, 10]);
@@ -6050,7 +7383,7 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
6050
7383
  _h.label = 8;
6051
7384
  case 8: return [3 /*break*/, 10];
6052
7385
  case 9:
6053
- if (e_13) throw e_13.error;
7386
+ if (e_24) throw e_24.error;
6054
7387
  return [7 /*endfinally*/];
6055
7388
  case 10: return [7 /*endfinally*/];
6056
7389
  case 11: throw new CodexWorkerBootstrapError('Codex worker exited before completing.');
@@ -6438,7 +7771,7 @@ function normalizeRouteMatchKey(value) {
6438
7771
  return normalizeRouteKey(value).toLowerCase();
6439
7772
  }
6440
7773
  function buildClientRouteIndex() {
6441
- var e_14, _a;
7774
+ var e_25, _a;
6442
7775
  var _b;
6443
7776
  var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
6444
7777
  var set = new Set();
@@ -6457,12 +7790,12 @@ function buildClientRouteIndex() {
6457
7790
  }
6458
7791
  }
6459
7792
  }
6460
- catch (e_14_1) { e_14 = { error: e_14_1 }; }
7793
+ catch (e_25_1) { e_25 = { error: e_25_1 }; }
6461
7794
  finally {
6462
7795
  try {
6463
7796
  if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
6464
7797
  }
6465
- finally { if (e_14) throw e_14.error; }
7798
+ finally { if (e_25) throw e_25.error; }
6466
7799
  }
6467
7800
  return { set: set, map: map, size: routes.length };
6468
7801
  }
@@ -6605,7 +7938,7 @@ function sanitizeAssistantResponse(value) {
6605
7938
  return normalizeAssistantRoutes(normalizedCurrency);
6606
7939
  }
6607
7940
  function evaluateAssistantGuardrails(message) {
6608
- var e_15, _a;
7941
+ var e_26, _a;
6609
7942
  var normalized = String(message || '').toLowerCase();
6610
7943
  var patterns = [
6611
7944
  {
@@ -6651,12 +7984,12 @@ function evaluateAssistantGuardrails(message) {
6651
7984
  }
6652
7985
  }
6653
7986
  }
6654
- catch (e_15_1) { e_15 = { error: e_15_1 }; }
7987
+ catch (e_26_1) { e_26 = { error: e_26_1 }; }
6655
7988
  finally {
6656
7989
  try {
6657
7990
  if (patterns_1_1 && !patterns_1_1.done && (_a = patterns_1.return)) _a.call(patterns_1);
6658
7991
  }
6659
- finally { if (e_15) throw e_15.error; }
7992
+ finally { if (e_26) throw e_26.error; }
6660
7993
  }
6661
7994
  return null;
6662
7995
  }
@@ -6771,7 +8104,7 @@ function tokenizeArithmeticExpression(expression) {
6771
8104
  return tokens;
6772
8105
  }
6773
8106
  function evaluateArithmeticExpression(expression) {
6774
- var e_16, _a, e_17, _b;
8107
+ var e_27, _a, e_28, _b;
6775
8108
  var tokens = tokenizeArithmeticExpression(expression);
6776
8109
  if (!tokens || !tokens.length) {
6777
8110
  return null;
@@ -6828,12 +8161,12 @@ function evaluateArithmeticExpression(expression) {
6828
8161
  prevToken = token;
6829
8162
  }
6830
8163
  }
6831
- catch (e_16_1) { e_16 = { error: e_16_1 }; }
8164
+ catch (e_27_1) { e_27 = { error: e_27_1 }; }
6832
8165
  finally {
6833
8166
  try {
6834
8167
  if (tokens_1_1 && !tokens_1_1.done && (_a = tokens_1.return)) _a.call(tokens_1);
6835
8168
  }
6836
- finally { if (e_16) throw e_16.error; }
8169
+ finally { if (e_27) throw e_27.error; }
6837
8170
  }
6838
8171
  while (ops.length) {
6839
8172
  var op = ops.pop();
@@ -6873,12 +8206,12 @@ function evaluateArithmeticExpression(expression) {
6873
8206
  stack.push(Number(token));
6874
8207
  }
6875
8208
  }
6876
- catch (e_17_1) { e_17 = { error: e_17_1 }; }
8209
+ catch (e_28_1) { e_28 = { error: e_28_1 }; }
6877
8210
  finally {
6878
8211
  try {
6879
8212
  if (output_1_1 && !output_1_1.done && (_b = output_1.return)) _b.call(output_1);
6880
8213
  }
6881
- finally { if (e_17) throw e_17.error; }
8214
+ finally { if (e_28) throw e_28.error; }
6882
8215
  }
6883
8216
  if (stack.length !== 1 || Number.isNaN(stack[0])) {
6884
8217
  return null;
@@ -7062,8 +8395,8 @@ function handleCodexUpload(id_conversation, file_name, content_base64, size, con
7062
8395
  }
7063
8396
  function readAttachmentContents(attachments) {
7064
8397
  return __awaiter(this, void 0, void 0, function () {
7065
- var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_18_1;
7066
- var e_18, _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;
7067
8400
  return __generator(this, function (_c) {
7068
8401
  switch (_c.label) {
7069
8402
  case 0:
@@ -7142,14 +8475,14 @@ function readAttachmentContents(attachments) {
7142
8475
  return [3 /*break*/, 2];
7143
8476
  case 10: return [3 /*break*/, 13];
7144
8477
  case 11:
7145
- e_18_1 = _c.sent();
7146
- e_18 = { error: e_18_1 };
8478
+ e_29_1 = _c.sent();
8479
+ e_29 = { error: e_29_1 };
7147
8480
  return [3 /*break*/, 13];
7148
8481
  case 12:
7149
8482
  try {
7150
8483
  if (attachments_1_1 && !attachments_1_1.done && (_b = attachments_1.return)) _b.call(attachments_1);
7151
8484
  }
7152
- finally { if (e_18) throw e_18.error; }
8485
+ finally { if (e_29) throw e_29.error; }
7153
8486
  return [7 /*endfinally*/];
7154
8487
  case 13: return [2 /*return*/, {
7155
8488
  promptText: chunks.length ? "\n\nAttachments:\n".concat(chunks.join('\n\n')) : '',
@@ -7270,6 +8603,17 @@ function normalizeOptionalString(value) {
7270
8603
  var raw = typeof value === 'string' ? value.trim() : '';
7271
8604
  return raw || '';
7272
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
+ }
7273
8617
  function normalizeConversationMode(value) {
7274
8618
  var normalized = normalizeOptionalString(value).toLowerCase();
7275
8619
  if (normalized === 'codex') {
@@ -7326,7 +8670,7 @@ function estimateUsage(messages, responseText, model) {
7326
8670
  };
7327
8671
  }
7328
8672
  function evaluateGuardrails(message) {
7329
- var e_19, _a;
8673
+ var e_30, _a;
7330
8674
  var normalized = String(message || '').toLowerCase();
7331
8675
  var patterns = [
7332
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.' },
@@ -7348,12 +8692,12 @@ function evaluateGuardrails(message) {
7348
8692
  }
7349
8693
  }
7350
8694
  }
7351
- catch (e_19_1) { e_19 = { error: e_19_1 }; }
8695
+ catch (e_30_1) { e_30 = { error: e_30_1 }; }
7352
8696
  finally {
7353
8697
  try {
7354
8698
  if (patterns_2_1 && !patterns_2_1.done && (_a = patterns_2.return)) _a.call(patterns_2);
7355
8699
  }
7356
- finally { if (e_19) throw e_19.error; }
8700
+ finally { if (e_30) throw e_30.error; }
7357
8701
  }
7358
8702
  return null;
7359
8703
  }