@resolveio/server-lib 22.1.8 → 22.1.10

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.
@@ -128,6 +128,7 @@ exports.rewriteEmbeddedMatchObjects = rewriteEmbeddedMatchObjects;
128
128
  exports.resolveAssistantCollectionOverride = resolveAssistantCollectionOverride;
129
129
  exports.resolveAssistantCrossCollectionFallbackCandidates = resolveAssistantCrossCollectionFallbackCandidates;
130
130
  exports.resolveAssistantAvailableCrossCollectionFallbacksFromNames = resolveAssistantAvailableCrossCollectionFallbacksFromNames;
131
+ exports.shouldAcceptAssistantFallbackDocuments = shouldAcceptAssistantFallbackDocuments;
131
132
  exports.collectUserViewPermissions = collectUserViewPermissions;
132
133
  exports.userHasInvoiceAccess = userHasInvoiceAccess;
133
134
  exports.resolveAssistantUserAccessTier = resolveAssistantUserAccessTier;
@@ -135,6 +136,7 @@ exports.resolveCodexThoughtLevel = resolveCodexThoughtLevel;
135
136
  exports.buildAssistantWorkspaceRootCandidates = buildAssistantWorkspaceRootCandidates;
136
137
  exports.classifyAssistantRequestType = classifyAssistantRequestType;
137
138
  exports.shouldRunAssistantPlanner = shouldRunAssistantPlanner;
139
+ exports.shouldEnforceAssistantDatedDirective = shouldEnforceAssistantDatedDirective;
138
140
  exports.collectAssistantAllowedRoutesForUser = collectAssistantAllowedRoutesForUser;
139
141
  exports.rankAssistantNavigationRoutes = rankAssistantNavigationRoutes;
140
142
  exports.shouldUseAssistantNavigationFastPath = shouldUseAssistantNavigationFastPath;
@@ -350,8 +352,59 @@ var AI_ASSISTANT_COLLECTION_DOMAIN_TOKENS = new Set([
350
352
  'orders',
351
353
  'delivery',
352
354
  'deliveries',
355
+ 'asset',
356
+ 'assets',
357
+ 'treatment',
358
+ 'treatments',
359
+ 'treatmentplan',
360
+ 'treatmentplans',
361
+ 'dispatch',
362
+ 'driver',
363
+ 'drivers',
364
+ 'treater',
365
+ 'specialty',
366
+ 'specialtyjob',
367
+ 'specialtyjobs',
368
+ 'bol',
369
+ 'bols',
370
+ 'lading',
371
+ 'pso',
372
+ 'psos',
373
+ 'po',
374
+ 'pos',
375
+ 'ats',
376
+ 'automated',
377
+ 'automation',
378
+ 'continuous',
379
+ 'isotank',
380
+ 'isotanks',
381
+ 'trailer',
382
+ 'trailers',
383
+ 'chemicaltrailer',
384
+ 'chemicaltrailers',
385
+ 'vac',
386
+ 'vactruck',
387
+ 'vactrucks',
388
+ 'purchase',
389
+ 'purchasing',
390
+ 'purchaseorder',
391
+ 'purchaseorders',
392
+ 'batchjob',
393
+ 'batchjobs',
394
+ 'production',
395
+ 'salesorder',
396
+ 'salesorders',
353
397
  'truck',
398
+ 'trucktreat',
399
+ 'trucktreating',
400
+ 'product',
401
+ 'products',
402
+ 'item',
403
+ 'items',
404
+ 'inventory',
354
405
  'treating',
406
+ 'batchtreat',
407
+ 'batchtreating',
355
408
  'route',
356
409
  'routes',
357
410
  'well',
@@ -401,6 +454,21 @@ var AI_ASSISTANT_TERM_SYNONYMS = [
401
454
  label: 'support tickets',
402
455
  pattern: /\bsupport[\s-]*tickets?\b/i,
403
456
  expansions: ['support-tickets', 'support ticket', 'ticket hours', 'billable hours']
457
+ },
458
+ {
459
+ label: 'delivery aliases',
460
+ pattern: /\b(bols?|bills?\s+of\s+lading|pso(?:s)?|production\s+sales\s+orders?|sales\s+orders?|truck[\s_-]+treat(?:ing)?|treater[\s_-]+truck|batch[\s_-]+(?:treat(?:ing)?|jobs?)|specialty[\s_-]+jobs?|continuous|ats|automated[\s_-]+treatment[\s_-]+system|isotanks?|chemical[\s_-]+trailers?|vac[\s_-]+trucks?|assets?|treatment[\s_-]+plans?|treatments?)\b/i,
461
+ expansions: ['delivery', 'deliveries', 'dispatch', 'route', 'work-order-dynamics', 'work order dynamics', 'work-orders', 'jobs', 'treatments', 'treatment-plans', 'assets']
462
+ },
463
+ {
464
+ label: 'purchase order aliases',
465
+ pattern: /\b(po(?:s)?|purchase[\s_-]+orders?)\b/i,
466
+ expansions: ['orders', 'purchase-orders', 'purchase orders', 'purchase order']
467
+ },
468
+ {
469
+ label: 'chemical catalog aliases',
470
+ pattern: /\b(chemicals?|products?|items?)\b/i,
471
+ expansions: ['chemical', 'chemicals', 'product', 'products', 'item', 'items', 'inventory']
404
472
  }
405
473
  ];
406
474
  var AI_ASSISTANT_REPORT_BUILDER_EXPERT_PLAYBOOK = [
@@ -511,7 +579,9 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
511
579
  '- For troubleshooting, ask clarifying questions only when needed to proceed; otherwise answer directly, then give a short decision tree (If X, do Y; If not, do Z).',
512
580
  '- Provide checklists for common tasks, highlighting required fields and common pitfalls.',
513
581
  '- If asked "where is this set," give the screen/workflow name and navigation steps to reach it.',
514
- '- If asked "what changed," summarize release notes if known; if not available, say so and suggest where to check or offer a support ticket.',
582
+ '- If asked "what changed" or "how long has this feature been around," provide the most specific app-level timeline/details available from project history.',
583
+ '- For server-lib/client-lib/platform updates, keep implementation details high-level, but dates/release windows are allowed.',
584
+ '- If exact history is unavailable in this runtime, say repository history is not accessible here and provide the best-known approximate timeframe.',
515
585
  '- After answering, optionally suggest 0-1 related next steps only when helpful. Do not ask for "next steps" every time.',
516
586
  '- If access is blocked, name the permission/role needed and how to request it.',
517
587
  '- Avoid vague labels like "Operations app"; use the specific screen/workflow name.',
@@ -2239,6 +2309,7 @@ function executeAiAssistantCodexRun(payload, context) {
2239
2309
  case 45:
2240
2310
  _j = _13.sent();
2241
2311
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
2312
+ assistantContent = applyAssistantDisplayTableToResponse(assistantContent, toolPayload.result.output.display);
2242
2313
  return [3 /*break*/, 46];
2243
2314
  case 46: return [3 /*break*/, 48];
2244
2315
  case 47:
@@ -2545,7 +2616,7 @@ function executeAiAssistantReportIssue(payload, context) {
2545
2616
  }
2546
2617
  function executeAiAssistantMongoRead(payload, context) {
2547
2618
  return __awaiter(this, void 0, void 0, function () {
2548
- var input, rawCollection, retryState, triedCollections, crossCollectionRetryEnabled, dbName, db, collectionResolution, collection, bridgeCollection, retryRootCollection, schemaFields, effectivePermissionView, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, strippedClient, clientScopedQuery, scopedQuery, normalized, findOptions, runFindWithRepair, initialRead, documents, executedQuery, probeDocs, dateFallback, fallbackQuery, fallbackRead, fallbackDocs, expanded, fallbackRead, fallbackDocs, nameFallback, fallbackRead, fallbackDocs, _c, chemicalLookup, fallbackRead, fallbackDocs, queryFields, _d, aliases, rewrittenQuery, fallbackRead, fallbackDocs, _e, activeFallback, fallbackRead, fallbackDocs, _f, idLookup, fallbackRead, fallbackDocs, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, crossCollectionCandidates, crossCollectionCandidates_1, crossCollectionCandidates_1_1, candidateCollection, fallbackPayload, fallbackResult, existingFallbacks, e_1_1, nameFields, dateFields, diagnostics, queryNoName, _g, queryNoDate, _h, _j, _k, _l, allCollections, base, alt, altCount, _m, total, sanitizedDocuments, requestedFields, missingFields, _o, projectionAliases, expandedProjection, refreshedDocs, includeIds, fieldAliases, displayDocs, idLookupDisplay, priorityFields, displayMaxRows, display;
2619
+ var input, rawCollection, retryState, triedCollections, crossCollectionRetryEnabled, dbName, db, collectionResolution, collection, bridgeCollection, retryRootCollection, schemaFields, effectivePermissionView, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, strippedClient, clientScopedQuery, scopedQuery, normalized, findOptions, runFindWithRepair, initialRead, documents, executedQuery, probeDocs, dateFallback, fallbackQuery, fallbackRead, fallbackDocs, expanded, fallbackRead, fallbackDocs, nameFallback, fallbackRead, fallbackDocs, _c, chemicalLookup, fallbackRead, fallbackDocs, queryFields, _d, aliases, rewrittenQuery, fallbackRead, fallbackDocs, _e, activeFallback, fallbackRead, fallbackDocs, _f, idLookup, fallbackRead, fallbackDocs, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, hasActiveStatusFilters, crossCollectionCandidates, crossCollectionCandidates_1, crossCollectionCandidates_1_1, candidateCollection, fallbackPayload, fallbackResult, fallbackDocs, existingFallbacks, rejectedQuality, e_1_1, nameFields, dateFields, diagnostics, queryNoName, _g, queryNoDate, _h, _j, _k, _l, allCollections, base, alt, altCount, _m, total, sanitizedDocuments, requestedFields, missingFields, _o, projectionAliases, expandedProjection, refreshedDocs, includeIds, fieldAliases, displayDocs, idLookupDisplay, priorityFields, displayMaxRows, display;
2549
2620
  var e_1, _p;
2550
2621
  var _this = this;
2551
2622
  var _q, _r;
@@ -2841,7 +2912,7 @@ function executeAiAssistantMongoRead(payload, context) {
2841
2912
  _s.label = 24;
2842
2913
  case 24:
2843
2914
  probeDocs = _e;
2844
- activeFallback = resolveReadActiveStatusFallback(executedQuery, probeDocs || []);
2915
+ activeFallback = resolveReadActiveStatusFallback(executedQuery, probeDocs || [], schemaFields);
2845
2916
  if (!activeFallback) return [3 /*break*/, 26];
2846
2917
  fallbackMeta.activeStatus = {
2847
2918
  fields: activeFallback.fields,
@@ -2930,7 +3001,8 @@ function executeAiAssistantMongoRead(payload, context) {
2930
3001
  }
2931
3002
  _s.label = 34;
2932
3003
  case 34:
2933
- if (!(!documents.length && crossCollectionRetryEnabled)) return [3 /*break*/, 43];
3004
+ hasActiveStatusFilters = collectAssistantActiveMatchFields(executedQuery).length > 0;
3005
+ if (!(!documents.length && crossCollectionRetryEnabled && !hasActiveStatusFilters)) return [3 /*break*/, 44];
2934
3006
  return [4 /*yield*/, resolveAssistantAvailableCrossCollectionFallbacks(db, dbName, collection, triedCollections)];
2935
3007
  case 35:
2936
3008
  crossCollectionCandidates = _s.sent();
@@ -2958,7 +3030,8 @@ function executeAiAssistantMongoRead(payload, context) {
2958
3030
  return [4 /*yield*/, executeAiAssistantMongoRead(fallbackPayload, context)];
2959
3031
  case 38:
2960
3032
  fallbackResult = _s.sent();
2961
- if (Array.isArray(fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.documents) && fallbackResult.documents.length) {
3033
+ fallbackDocs = Array.isArray(fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.documents) ? fallbackResult.documents : [];
3034
+ if (fallbackDocs.length && shouldAcceptAssistantFallbackDocuments(fallbackDocs)) {
2962
3035
  if (isSuperAdmin && (fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.debug) && typeof fallbackResult.debug === 'object') {
2963
3036
  existingFallbacks = fallbackResult.debug.fallbacks && typeof fallbackResult.debug.fallbacks === 'object'
2964
3037
  ? fallbackResult.debug.fallbacks
@@ -2973,6 +3046,16 @@ function executeAiAssistantMongoRead(payload, context) {
2973
3046
  }
2974
3047
  return [2 /*return*/, fallbackResult];
2975
3048
  }
3049
+ if (fallbackDocs.length && isSuperAdmin && fallbackMeta.collectionRetry && typeof fallbackMeta.collectionRetry === 'object') {
3050
+ rejectedQuality = Array.isArray(fallbackMeta.collectionRetry.rejectedQuality)
3051
+ ? fallbackMeta.collectionRetry.rejectedQuality
3052
+ : [];
3053
+ rejectedQuality.push({
3054
+ collection: candidateCollection,
3055
+ reason: 'empty_dimension_values'
3056
+ });
3057
+ fallbackMeta.collectionRetry.rejectedQuality = rejectedQuality;
3058
+ }
2976
3059
  _s.label = 39;
2977
3060
  case 39:
2978
3061
  crossCollectionCandidates_1_1 = crossCollectionCandidates_1.next();
@@ -2988,8 +3071,20 @@ function executeAiAssistantMongoRead(payload, context) {
2988
3071
  }
2989
3072
  finally { if (e_1) throw e_1.error; }
2990
3073
  return [7 /*endfinally*/];
2991
- case 43:
2992
- if (!(!documents.length && isSuperAdmin)) return [3 /*break*/, 60];
3074
+ case 43: return [3 /*break*/, 45];
3075
+ case 44:
3076
+ if (!documents.length && crossCollectionRetryEnabled && hasActiveStatusFilters && isSuperAdmin) {
3077
+ fallbackMeta.collectionRetry = {
3078
+ from: collection,
3079
+ root: retryRootCollection,
3080
+ attempted: false,
3081
+ skipped: true,
3082
+ reason: 'active_status_query_preserved'
3083
+ };
3084
+ }
3085
+ _s.label = 45;
3086
+ case 45:
3087
+ if (!(!documents.length && isSuperAdmin)) return [3 /*break*/, 62];
2993
3088
  nameFields = collectMatchFieldsByCondition(executedQuery, function (field, condition) { return isRegexMatchCondition(condition)
2994
3089
  || (typeof condition === 'string' && shouldApplyAssistantNameRegex(field)); });
2995
3090
  dateFields = collectMatchFieldsByCondition(executedQuery, function (_field, condition) { return isDateCondition(condition); });
@@ -2997,36 +3092,36 @@ function executeAiAssistantMongoRead(payload, context) {
2997
3092
  nameFields: nameFields.length ? nameFields : undefined,
2998
3093
  dateFields: dateFields.length ? dateFields : undefined
2999
3094
  };
3000
- _s.label = 44;
3001
- case 44:
3002
- _s.trys.push([44, 49, , 50]);
3003
- if (!nameFields.length) return [3 /*break*/, 46];
3095
+ _s.label = 46;
3096
+ case 46:
3097
+ _s.trys.push([46, 51, , 52]);
3098
+ if (!nameFields.length) return [3 /*break*/, 48];
3004
3099
  queryNoName = stripMatchFields(executedQuery, nameFields);
3005
3100
  _g = diagnostics;
3006
3101
  return [4 /*yield*/, db.collection(collection).countDocuments(queryNoName, {
3007
3102
  readPreference: AI_ASSISTANT_READ_PREFERENCE
3008
3103
  })];
3009
- case 45:
3104
+ case 47:
3010
3105
  _g.recentCount = _s.sent();
3011
- _s.label = 46;
3012
- case 46:
3013
- if (!dateFields.length) return [3 /*break*/, 48];
3106
+ _s.label = 48;
3107
+ case 48:
3108
+ if (!dateFields.length) return [3 /*break*/, 50];
3014
3109
  queryNoDate = stripMatchFields(executedQuery, dateFields);
3015
3110
  _h = diagnostics;
3016
3111
  return [4 /*yield*/, db.collection(collection).countDocuments(queryNoDate, {
3017
3112
  readPreference: AI_ASSISTANT_READ_PREFERENCE
3018
3113
  })];
3019
- case 47:
3020
- _h.nameMatchCount = _s.sent();
3021
- _s.label = 48;
3022
- case 48: return [3 /*break*/, 50];
3023
3114
  case 49:
3115
+ _h.nameMatchCount = _s.sent();
3116
+ _s.label = 50;
3117
+ case 50: return [3 /*break*/, 52];
3118
+ case 51:
3024
3119
  _j = _s.sent();
3025
- return [3 /*break*/, 50];
3026
- case 50:
3027
- _s.trys.push([50, 53, , 54]);
3120
+ return [3 /*break*/, 52];
3121
+ case 52:
3122
+ _s.trys.push([52, 55, , 56]);
3028
3123
  _k = probeDocs;
3029
- if (_k) return [3 /*break*/, 52];
3124
+ if (_k) return [3 /*break*/, 54];
3030
3125
  return [4 /*yield*/, fetchAssistantProbeDocs({
3031
3126
  db: db,
3032
3127
  collection: collection,
@@ -3035,56 +3130,56 @@ function executeAiAssistantMongoRead(payload, context) {
3035
3130
  isSuperAdmin: isSuperAdmin,
3036
3131
  includeClientScope: shouldScopeByClient
3037
3132
  })];
3038
- case 51:
3133
+ case 53:
3039
3134
  _k = (_s.sent());
3040
- _s.label = 52;
3041
- case 52:
3135
+ _s.label = 54;
3136
+ case 54:
3042
3137
  probeDocs = _k;
3043
3138
  if (probeDocs.length && nameFields.length) {
3044
3139
  diagnostics.chemicalIdDetected = detectChemicalIdFromProbe(probeDocs, nameFields);
3045
3140
  }
3046
- return [3 /*break*/, 54];
3047
- case 53:
3141
+ return [3 /*break*/, 56];
3142
+ case 55:
3048
3143
  _l = _s.sent();
3049
- return [3 /*break*/, 54];
3050
- case 54:
3051
- _s.trys.push([54, 58, , 59]);
3144
+ return [3 /*break*/, 56];
3145
+ case 56:
3146
+ _s.trys.push([56, 60, , 61]);
3052
3147
  return [4 /*yield*/, listAssistantCollections(db, dbName)];
3053
- case 55:
3148
+ case 57:
3054
3149
  allCollections = _s.sent();
3055
3150
  base = stripVersionSuffix(collection.startsWith('report-') ? collection.slice('report-'.length) : collection);
3056
3151
  alt = collection.startsWith('report-') ? base : "report-".concat(base);
3057
- if (!(alt && alt !== collection && allCollections.includes(alt))) return [3 /*break*/, 57];
3152
+ if (!(alt && alt !== collection && allCollections.includes(alt))) return [3 /*break*/, 59];
3058
3153
  return [4 /*yield*/, db.collection(alt).countDocuments({}, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
3059
- case 56:
3154
+ case 58:
3060
3155
  altCount = _s.sent();
3061
3156
  diagnostics.alternateCollection = alt;
3062
3157
  diagnostics.alternateCollectionCount = altCount;
3063
- _s.label = 57;
3064
- case 57: return [3 /*break*/, 59];
3065
- case 58:
3158
+ _s.label = 59;
3159
+ case 59: return [3 /*break*/, 61];
3160
+ case 60:
3066
3161
  _m = _s.sent();
3067
- return [3 /*break*/, 59];
3068
- case 59:
3162
+ return [3 /*break*/, 61];
3163
+ case 61:
3069
3164
  fallbackMeta.zeroDiagnostics = diagnostics;
3070
- _s.label = 60;
3071
- case 60:
3165
+ _s.label = 62;
3166
+ case 62:
3072
3167
  total = null;
3073
- if (!normalized.includeTotal) return [3 /*break*/, 62];
3168
+ if (!normalized.includeTotal) return [3 /*break*/, 64];
3074
3169
  return [4 /*yield*/, db.collection(collection).countDocuments(executedQuery, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
3075
- case 61:
3170
+ case 63:
3076
3171
  total = _s.sent();
3077
- _s.label = 62;
3078
- case 62:
3172
+ _s.label = 64;
3173
+ case 64:
3079
3174
  sanitizedDocuments = isSuperAdmin
3080
3175
  ? documents
3081
3176
  : documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
3082
3177
  requestedFields = resolveProjectionRequestedFields(findOptions.projection);
3083
- if (!(sanitizedDocuments.length && requestedFields.length)) return [3 /*break*/, 66];
3178
+ if (!(sanitizedDocuments.length && requestedFields.length)) return [3 /*break*/, 68];
3084
3179
  missingFields = requestedFields.filter(function (field) { return !hasNonEmptyValue(sanitizedDocuments, field, { treatObjectLikeAsEmpty: true }); });
3085
- if (!missingFields.length) return [3 /*break*/, 66];
3180
+ if (!missingFields.length) return [3 /*break*/, 68];
3086
3181
  _o = probeDocs;
3087
- if (_o) return [3 /*break*/, 64];
3182
+ if (_o) return [3 /*break*/, 66];
3088
3183
  return [4 /*yield*/, fetchAssistantProbeDocs({
3089
3184
  db: db,
3090
3185
  collection: collection,
@@ -3093,25 +3188,25 @@ function executeAiAssistantMongoRead(payload, context) {
3093
3188
  isSuperAdmin: isSuperAdmin,
3094
3189
  includeClientScope: shouldScopeByClient
3095
3190
  })];
3096
- case 63:
3191
+ case 65:
3097
3192
  _o = (_s.sent());
3098
- _s.label = 64;
3099
- case 64:
3193
+ _s.label = 66;
3194
+ case 66:
3100
3195
  probeDocs = _o;
3101
- if (!probeDocs.length) return [3 /*break*/, 66];
3196
+ if (!probeDocs.length) return [3 /*break*/, 68];
3102
3197
  projectionAliases = resolveFieldAliases(probeDocs, missingFields, schemaFields);
3103
- if (!Object.keys(projectionAliases).length) return [3 /*break*/, 66];
3198
+ if (!Object.keys(projectionAliases).length) return [3 /*break*/, 68];
3104
3199
  fallbackMeta.projectionAliases = {
3105
3200
  aliases: projectionAliases,
3106
3201
  attempted: true,
3107
3202
  used: false
3108
3203
  };
3109
3204
  expandedProjection = expandProjectionWithAliases(findOptions.projection, projectionAliases);
3110
- if (!(expandedProjection && expandedProjection !== findOptions.projection)) return [3 /*break*/, 66];
3205
+ if (!(expandedProjection && expandedProjection !== findOptions.projection)) return [3 /*break*/, 68];
3111
3206
  findOptions = __assign(__assign({}, findOptions), { projection: expandedProjection });
3112
3207
  normalized.findOptions.projection = expandedProjection;
3113
3208
  return [4 /*yield*/, db.collection(collection).find(executedQuery, findOptions).toArray()];
3114
- case 65:
3209
+ case 67:
3115
3210
  refreshedDocs = _s.sent();
3116
3211
  if (refreshedDocs.length) {
3117
3212
  documents = refreshedDocs;
@@ -3120,8 +3215,8 @@ function executeAiAssistantMongoRead(payload, context) {
3120
3215
  : refreshedDocs.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
3121
3216
  fallbackMeta.projectionAliases.used = true;
3122
3217
  }
3123
- _s.label = 66;
3124
- case 66:
3218
+ _s.label = 68;
3219
+ case 68:
3125
3220
  includeIds = ((_r = input.options) === null || _r === void 0 ? void 0 : _r.includeIds) === true;
3126
3221
  fieldAliases = resolveFieldAliases(sanitizedDocuments, requestedFields, schemaFields);
3127
3222
  displayDocs = Object.keys(fieldAliases).length
@@ -3136,7 +3231,7 @@ function executeAiAssistantMongoRead(payload, context) {
3136
3231
  idCustomer: customerId,
3137
3232
  isSuperAdmin: isSuperAdmin
3138
3233
  })];
3139
- case 67:
3234
+ case 69:
3140
3235
  idLookupDisplay = _s.sent();
3141
3236
  if (idLookupDisplay === null || idLookupDisplay === void 0 ? void 0 : idLookupDisplay.docs) {
3142
3237
  displayDocs = idLookupDisplay.docs;
@@ -3182,7 +3277,7 @@ function executeAiAssistantMongoRead(payload, context) {
3182
3277
  }
3183
3278
  function executeAiAssistantMongoAggregate(payload, context) {
3184
3279
  return __awaiter(this, void 0, void 0, function () {
3185
- var input, rawCollection, retryState, triedCollections, crossCollectionRetryEnabled, dbName, db, collectionResolution, collection, bridgeCollection, retryRootCollection, schemaFields, effectivePermissionView, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, sanitizedPipeline, strippedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, executedPipeline, dateField, aggregateOptions, runAggregateWithRepair, initialAggregate, documents, probeDocs, fallback, fallbackPipeline, fallbackAggregate, fallbackDocs, createdFallback, createdPipeline, createdAggregate, createdDocs, expanded, expandedAggregate, expandedDocs, completionFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, completionExprFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, unwindFallback, shouldUnwind, _c, _d, fallbackPipeline, fallbackAggregate, fallbackDocs, nameFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, _e, _loop_1, i, state_1, matchFields_1, _f, aliases, rewrittenPipeline, fallbackAggregate, fallbackDocs, _loop_2, i, state_2, nestedFallbacks, nestedFallbacks_1, nestedFallbacks_1_1, nestedFallback, fallbackPayload, fallbackResult, existingFallbacks, error_6, errorMessage, existingErrors, e_2_1, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, crossCollectionCandidates, crossCollectionCandidates_2, crossCollectionCandidates_2_1, candidateCollection, fallbackPayload, fallbackResult, existingFallbacks, e_3_1, matchStages, diagnostics, combinedMatch, nameFields, dateFields, queryNoName, _g, queryNoDate, _h, _j, _k, _l, allCollections, base, alt, altCount, _m, verification, sanitizedDocuments, includeIds, displayDocs, idLookupDisplay, display;
3280
+ var input, rawCollection, retryState, triedCollections, crossCollectionRetryEnabled, dbName, db, collectionResolution, collection, bridgeCollection, retryRootCollection, schemaFields, effectivePermissionView, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, sanitizedPipeline, strippedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, executedPipeline, dateField, aggregateOptions, runAggregateWithRepair, initialAggregate, documents, probeDocs, fallback, fallbackPipeline, fallbackAggregate, fallbackDocs, createdFallback, createdPipeline, createdAggregate, createdDocs, expanded, expandedAggregate, expandedDocs, completionFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, completionExprFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, unwindFallback, shouldUnwind, _c, _d, fallbackPipeline, fallbackAggregate, fallbackDocs, nameFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, _e, _loop_1, i, state_1, matchFields_1, _f, aliases, rewrittenPipeline, fallbackAggregate, fallbackDocs, _loop_2, i, state_2, nestedFallbacks, nestedFallbacks_1, nestedFallbacks_1_1, nestedFallback, fallbackPayload, fallbackResult, existingFallbacks, error_6, errorMessage, existingErrors, e_2_1, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, crossCollectionCandidates, crossCollectionCandidates_2, crossCollectionCandidates_2_1, candidateCollection, fallbackPayload, fallbackResult, fallbackDocs, existingFallbacks, rejectedQuality, e_3_1, matchStages, diagnostics, combinedMatch, nameFields, dateFields, queryNoName, _g, queryNoDate, _h, _j, _k, _l, allCollections, base, alt, altCount, _m, verification, sanitizedDocuments, includeIds, displayDocs, idLookupDisplay, display;
3186
3281
  var e_2, _o, e_3, _p;
3187
3282
  var _this = this;
3188
3283
  var _q, _r;
@@ -3293,7 +3388,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
3293
3388
  }
3294
3389
  aggregateOptions = __assign(__assign({}, normalizedOptions.aggregateOptions), { readPreference: AI_ASSISTANT_READ_PREFERENCE });
3295
3390
  runAggregateWithRepair = function (pipeline, stage) { return __awaiter(_this, void 0, void 0, function () {
3296
- var docs, error_7, isDateRepair, isRankSortByRepair, repaired, docs;
3391
+ var docs, error_7, isDateRepair, isRankSortByRepair, isDottedOutputFieldRepair, repaired, docs;
3297
3392
  return __generator(this, function (_a) {
3298
3393
  switch (_a.label) {
3299
3394
  case 0:
@@ -3308,12 +3403,15 @@ function executeAiAssistantMongoAggregate(payload, context) {
3308
3403
  error_7 = _a.sent();
3309
3404
  isDateRepair = isAssistantDateArithmeticArgumentError(error_7);
3310
3405
  isRankSortByRepair = isAssistantRankSortByError(error_7);
3311
- if (!isDateRepair && !isRankSortByRepair) {
3406
+ isDottedOutputFieldRepair = isAssistantDottedOutputFieldError(error_7);
3407
+ if (!isDateRepair && !isRankSortByRepair && !isDottedOutputFieldRepair) {
3312
3408
  throw error_7;
3313
3409
  }
3314
3410
  repaired = isDateRepair
3315
3411
  ? repairAssistantDateArithmeticInPipeline(pipeline)
3316
- : repairAssistantRankSortByInPipeline(pipeline);
3412
+ : isRankSortByRepair
3413
+ ? repairAssistantRankSortByInPipeline(pipeline)
3414
+ : repairAssistantDottedOutputFieldNamesInPipeline(pipeline);
3317
3415
  if (!repaired.changed || containsForbiddenMongoOperators(repaired.pipeline)) {
3318
3416
  throw error_7;
3319
3417
  }
@@ -3338,6 +3436,14 @@ function executeAiAssistantMongoAggregate(payload, context) {
3338
3436
  reason: 'normalized_rank_sortby_single_key'
3339
3437
  };
3340
3438
  }
3439
+ if (isDottedOutputFieldRepair) {
3440
+ fallbackMeta.outputFieldPath = {
3441
+ attempted: true,
3442
+ used: true,
3443
+ stage: stage,
3444
+ reason: 'normalized_dotted_output_field_names'
3445
+ };
3446
+ }
3341
3447
  return [2 /*return*/, { documents: docs, pipeline: repaired.pipeline }];
3342
3448
  case 4: return [2 /*return*/];
3343
3449
  }
@@ -3856,7 +3962,8 @@ function executeAiAssistantMongoAggregate(payload, context) {
3856
3962
  return [4 /*yield*/, executeAiAssistantMongoAggregate(fallbackPayload, context)];
3857
3963
  case 60:
3858
3964
  fallbackResult = _s.sent();
3859
- if (Array.isArray(fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.documents) && fallbackResult.documents.length) {
3965
+ fallbackDocs = Array.isArray(fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.documents) ? fallbackResult.documents : [];
3966
+ if (fallbackDocs.length && shouldAcceptAssistantFallbackDocuments(fallbackDocs)) {
3860
3967
  if (isSuperAdmin && (fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.debug) && typeof fallbackResult.debug === 'object') {
3861
3968
  existingFallbacks = fallbackResult.debug.fallbacks && typeof fallbackResult.debug.fallbacks === 'object'
3862
3969
  ? fallbackResult.debug.fallbacks
@@ -3871,6 +3978,16 @@ function executeAiAssistantMongoAggregate(payload, context) {
3871
3978
  }
3872
3979
  return [2 /*return*/, fallbackResult];
3873
3980
  }
3981
+ if (fallbackDocs.length && isSuperAdmin && fallbackMeta.collectionRetry && typeof fallbackMeta.collectionRetry === 'object') {
3982
+ rejectedQuality = Array.isArray(fallbackMeta.collectionRetry.rejectedQuality)
3983
+ ? fallbackMeta.collectionRetry.rejectedQuality
3984
+ : [];
3985
+ rejectedQuality.push({
3986
+ collection: candidateCollection,
3987
+ reason: 'empty_dimension_values'
3988
+ });
3989
+ fallbackMeta.collectionRetry.rejectedQuality = rejectedQuality;
3990
+ }
3874
3991
  _s.label = 61;
3875
3992
  case 61:
3876
3993
  crossCollectionCandidates_2_1 = crossCollectionCandidates_2.next();
@@ -8401,31 +8518,127 @@ function ensureAssistantMinimumDisplayColumns(display) {
8401
8518
  : rows.length;
8402
8519
  return __assign(__assign({}, display), { columns: [primary, 'Count'], rows: [(_a = {}, _a[primary] = uniqueLabels[0], _a.Count = totalCount, _a)], rowCount: 1, truncated: false });
8403
8520
  }
8521
+ function resolveAssistantDisplayTemporalLabelHint(value) {
8522
+ var text = normalizeOptionalString(value).toLowerCase();
8523
+ if (!text) {
8524
+ return '';
8525
+ }
8526
+ var explicitCustomerGrouping = /\b(?:by|per)\s+(?:each\s+)?customer\b/.test(text)
8527
+ || /\bcustomer\s+breakdown\b/.test(text)
8528
+ || /\brevenue\s+by\s+customer\b/.test(text);
8529
+ if (explicitCustomerGrouping) {
8530
+ return 'Customer';
8531
+ }
8532
+ if (/\b(year|yearly|per year|by year)\b/.test(text)) {
8533
+ return 'Year';
8534
+ }
8535
+ if (/\b(quarter|quarterly|per quarter|by quarter)\b/.test(text)) {
8536
+ return 'Quarter';
8537
+ }
8538
+ if (/\b(month|monthly|per month|by month)\b/.test(text)) {
8539
+ return 'Month';
8540
+ }
8541
+ if (/\b(week|weekly|per week|by week)\b/.test(text)) {
8542
+ return 'Week';
8543
+ }
8544
+ if (/\b(day|daily|per day|by day|date)\b/.test(text)) {
8545
+ return 'Day';
8546
+ }
8547
+ if (/\b(customer|client)\b/.test(text)) {
8548
+ return 'Customer';
8549
+ }
8550
+ return '';
8551
+ }
8552
+ function renameAssistantDisplayColumn(display, fromColumn, toColumn) {
8553
+ var from = normalizeOptionalString(fromColumn);
8554
+ var to = normalizeOptionalString(toColumn);
8555
+ if (!from || !to || from === to || !Array.isArray(display === null || display === void 0 ? void 0 : display.columns)) {
8556
+ return display;
8557
+ }
8558
+ var index = display.columns.findIndex(function (column) { return normalizeOptionalString(column).toLowerCase() === from.toLowerCase(); });
8559
+ if (index === -1) {
8560
+ return display;
8561
+ }
8562
+ var sourceColumn = display.columns[index];
8563
+ var columns = __spreadArray([], __read(display.columns), false);
8564
+ columns[index] = to;
8565
+ var rows = Array.isArray(display.rows)
8566
+ ? display.rows.map(function (row) {
8567
+ var next = __assign({}, (row || {}));
8568
+ if (Object.prototype.hasOwnProperty.call(next, sourceColumn) && !Object.prototype.hasOwnProperty.call(next, to)) {
8569
+ next[to] = next[sourceColumn];
8570
+ delete next[sourceColumn];
8571
+ }
8572
+ return next;
8573
+ })
8574
+ : [];
8575
+ return __assign(__assign({}, display), { columns: columns, rows: rows });
8576
+ }
8577
+ function applyAssistantDisplayColumnHints(value, display) {
8578
+ if (!display || !Array.isArray(display.columns) || !display.columns.length) {
8579
+ return display;
8580
+ }
8581
+ var firstColumn = normalizeOptionalString(display.columns[0]).toLowerCase();
8582
+ if (firstColumn !== 'group' && firstColumn !== 'result') {
8583
+ return display;
8584
+ }
8585
+ var labelHint = resolveAssistantDisplayTemporalLabelHint(value);
8586
+ if (!labelHint) {
8587
+ return display;
8588
+ }
8589
+ return renameAssistantDisplayColumn(display, display.columns[0], labelHint);
8590
+ }
8591
+ function resolveAssistantEmptyDisplayColumns(value) {
8592
+ var labelHint = resolveAssistantDisplayTemporalLabelHint(value);
8593
+ if (labelHint) {
8594
+ if (labelHint === 'Customer') {
8595
+ var requestedMonths = resolveAssistantRequestedMonthBucketsFromMessage(value);
8596
+ if (requestedMonths.length >= 3) {
8597
+ return __spreadArray([labelHint], __read(requestedMonths), false);
8598
+ }
8599
+ var looseMonthMatch = value.match(/\b(?:last|past|previous|over\s+the\s+last)\s+(\d+)\s+(?:full\s+calendar\s+|calendar\s+|full\s+)?months?\b/i);
8600
+ var looseMonthCount = (looseMonthMatch === null || looseMonthMatch === void 0 ? void 0 : looseMonthMatch[1]) ? Number(looseMonthMatch[1]) : Number.NaN;
8601
+ if (Number.isFinite(looseMonthCount) && looseMonthCount > 0) {
8602
+ var inferred = buildAssistantExpectedMonthBuckets((0, common_1.round)(looseMonthCount), 'full_month');
8603
+ if (inferred.length >= 3) {
8604
+ return __spreadArray([labelHint], __read(inferred), false);
8605
+ }
8606
+ }
8607
+ return [labelHint, 'Details'];
8608
+ }
8609
+ return [labelHint, 'Total Revenue'];
8610
+ }
8611
+ if (hasAssistantDeliveryAliasTerms(value)) {
8612
+ return ['Delivery', 'Details'];
8613
+ }
8614
+ return ['Result', 'Details'];
8615
+ }
8404
8616
  function applyAssistantDisplayTableToResponse(value, display) {
8617
+ var _a;
8405
8618
  if (!display || !Array.isArray(display.rows)) {
8406
8619
  return value;
8407
8620
  }
8408
- var normalizedDisplay = ensureAssistantMinimumDisplayColumns(display);
8621
+ var normalizedDisplay = applyAssistantDisplayColumnHints(value, ensureAssistantMinimumDisplayColumns(display));
8409
8622
  if (!display.rows.length) {
8410
8623
  var cleaned_1 = stripAssistantMarkdownTables(value);
8411
8624
  var rowCount = typeof normalizedDisplay.rowCount === 'number' && normalizedDisplay.rowCount > 0
8412
8625
  ? normalizedDisplay.rowCount
8413
8626
  : 0;
8414
- var tableDisplay = rowCount > 0
8415
- ? {
8416
- columns: ['Metric', 'Value'],
8417
- rows: [{ Metric: 'Rows matched', Value: rowCount }],
8418
- rowCount: 1,
8419
- truncated: false,
8420
- includeIds: false
8421
- }
8422
- : {
8423
- columns: ['Result', 'Details'],
8424
- rows: [{ Result: 'No matching rows', Details: '' }],
8425
- rowCount: 0,
8426
- truncated: false,
8427
- includeIds: false
8428
- };
8627
+ var fallbackColumns = Array.isArray(normalizedDisplay.columns) && normalizedDisplay.columns.length
8628
+ ? normalizedDisplay.columns
8629
+ : resolveAssistantEmptyDisplayColumns(cleaned_1 || value);
8630
+ var normalizedColumns = fallbackColumns.length === 1
8631
+ ? __spreadArray(__spreadArray([], __read(fallbackColumns), false), ['Value'], false) : fallbackColumns;
8632
+ var rowSummary = rowCount > 0
8633
+ ? [(_a = {}, _a[normalizedColumns[0]] = 'Rows matched', _a[normalizedColumns[1]] = rowCount, _a)]
8634
+ : [];
8635
+ var tableDisplay = {
8636
+ columns: normalizedColumns,
8637
+ rows: rowSummary,
8638
+ rowCount: rowCount,
8639
+ truncated: false,
8640
+ includeIds: false
8641
+ };
8429
8642
  var emptyTable = formatDisplayTableMarkdown(tableDisplay);
8430
8643
  if (!emptyTable) {
8431
8644
  return cleaned_1 || value;
@@ -9200,10 +9413,63 @@ function normalizeAssistantDateArithmeticArgs(expression) {
9200
9413
  }
9201
9414
  expression.$let = nextArgs;
9202
9415
  };
9416
+ var normalizeDatePartArgs = function () {
9417
+ var operators = ['$year', '$month', '$week', '$isoWeek', '$isoWeekYear', '$dayOfMonth', '$dayOfYear'];
9418
+ var looksLikeDateOperand = function (candidate) {
9419
+ if (candidate instanceof Date) {
9420
+ return true;
9421
+ }
9422
+ if (typeof candidate === 'string') {
9423
+ return candidate.startsWith('$$') || candidate.startsWith('$');
9424
+ }
9425
+ if (candidate && typeof candidate === 'object' && !Array.isArray(candidate)) {
9426
+ return Object.keys(candidate).some(function (op) { return op.startsWith('$'); });
9427
+ }
9428
+ return false;
9429
+ };
9430
+ operators.forEach(function (operator) {
9431
+ if (!Object.prototype.hasOwnProperty.call(expression, operator)) {
9432
+ return;
9433
+ }
9434
+ var rawArgs = expression[operator];
9435
+ if (!rawArgs || typeof rawArgs !== 'object' || Array.isArray(rawArgs)) {
9436
+ return;
9437
+ }
9438
+ if (rawArgs instanceof Date || rawArgs instanceof RegExp || isMongoObjectId(rawArgs)) {
9439
+ return;
9440
+ }
9441
+ var nextArgs = __assign({}, rawArgs);
9442
+ if (!Object.prototype.hasOwnProperty.call(nextArgs, 'date')) {
9443
+ var dateCandidateKey = Object.keys(nextArgs).find(function (key) {
9444
+ if (key === 'timezone') {
9445
+ return false;
9446
+ }
9447
+ return looksLikeDateOperand(nextArgs[key]);
9448
+ });
9449
+ if (dateCandidateKey) {
9450
+ nextArgs.date = nextArgs[dateCandidateKey];
9451
+ delete nextArgs[dateCandidateKey];
9452
+ }
9453
+ }
9454
+ if (!Object.prototype.hasOwnProperty.call(nextArgs, 'date')) {
9455
+ return;
9456
+ }
9457
+ var allowedKeys = new Set(['date', 'timezone']);
9458
+ Object.keys(nextArgs).forEach(function (key) {
9459
+ if (!allowedKeys.has(key)) {
9460
+ delete nextArgs[key];
9461
+ }
9462
+ });
9463
+ expression[operator] = Object.prototype.hasOwnProperty.call(nextArgs, 'timezone')
9464
+ ? nextArgs
9465
+ : nextArgs.date;
9466
+ });
9467
+ };
9203
9468
  normalizeOperatorArgs('$dateAdd');
9204
9469
  normalizeOperatorArgs('$dateSubtract');
9205
9470
  normalizeDateTruncArgs();
9206
9471
  normalizeLetArgs();
9472
+ normalizeDatePartArgs();
9207
9473
  return expression;
9208
9474
  }
9209
9475
  function normalizeAssistantNowExprPlaceholdersDeep(value) {
@@ -9236,6 +9502,13 @@ function isAssistantDateArithmeticArgumentError(error) {
9236
9502
  return message.includes('unrecognized argument to $datesubtract:')
9237
9503
  || message.includes('unrecognized argument to $dateadd:')
9238
9504
  || message.includes('unrecognized argument to $datetrunc:')
9505
+ || message.includes('unrecognized option to $year:')
9506
+ || message.includes('unrecognized option to $month:')
9507
+ || message.includes('unrecognized option to $week:')
9508
+ || message.includes('unrecognized option to $isoweek:')
9509
+ || message.includes('unrecognized option to $isoweekyear:')
9510
+ || message.includes('unrecognized option to $dayofmonth:')
9511
+ || message.includes('unrecognized option to $dayofyear:')
9239
9512
  || message.includes('unrecognized parameter to $let:')
9240
9513
  || message.includes("missing 'in' parameter to $let")
9241
9514
  || message.includes("missing 'unit' parameter to $datetrunc")
@@ -9269,6 +9542,13 @@ function isAssistantRankSortByError(error) {
9269
9542
  return message.includes('$rank must be specified with a top level sortby expression with exactly one element')
9270
9543
  || message.includes('$denserank must be specified with a top level sortby expression with exactly one element');
9271
9544
  }
9545
+ function isAssistantDottedOutputFieldError(error) {
9546
+ var message = normalizeOptionalString(error === null || error === void 0 ? void 0 : error.message).toLowerCase();
9547
+ if (!message) {
9548
+ return false;
9549
+ }
9550
+ return message.includes("fieldpath field names may not contain '.'");
9551
+ }
9272
9552
  function didAssistantValueChange(before, after) {
9273
9553
  try {
9274
9554
  return JSON.stringify(before) !== JSON.stringify(after);
@@ -9314,6 +9594,49 @@ function repairAssistantRankSortByInPipeline(pipeline) {
9314
9594
  changed: didAssistantValueChange(pipeline, repaired)
9315
9595
  };
9316
9596
  }
9597
+ function repairAssistantDottedOutputFieldNamesInPipeline(pipeline) {
9598
+ var rewriteStageOutputFields = function (value) {
9599
+ if (Array.isArray(value)) {
9600
+ return value.map(function (entry) { return rewriteStageOutputFields(entry); });
9601
+ }
9602
+ if (!value || typeof value !== 'object' || value instanceof Date || value instanceof RegExp || isMongoObjectId(value)) {
9603
+ return value;
9604
+ }
9605
+ var next = {};
9606
+ Object.keys(value).forEach(function (field) {
9607
+ var safeField = field.startsWith('$') || field === '_id'
9608
+ ? field
9609
+ : field.replace(/\./g, '_');
9610
+ next[safeField] = rewriteStageOutputFields(value[field]);
9611
+ });
9612
+ return next;
9613
+ };
9614
+ var repaired = Array.isArray(pipeline)
9615
+ ? pipeline.map(function (stage) {
9616
+ if (!stage || typeof stage !== 'object' || Array.isArray(stage)) {
9617
+ return stage;
9618
+ }
9619
+ var next = __assign({}, stage);
9620
+ if (stage.$project && typeof stage.$project === 'object' && !Array.isArray(stage.$project)) {
9621
+ next.$project = rewriteStageOutputFields(stage.$project);
9622
+ }
9623
+ if (stage.$addFields && typeof stage.$addFields === 'object' && !Array.isArray(stage.$addFields)) {
9624
+ next.$addFields = rewriteStageOutputFields(stage.$addFields);
9625
+ }
9626
+ if (stage.$set && typeof stage.$set === 'object' && !Array.isArray(stage.$set)) {
9627
+ next.$set = rewriteStageOutputFields(stage.$set);
9628
+ }
9629
+ if (stage.$group && typeof stage.$group === 'object' && !Array.isArray(stage.$group)) {
9630
+ next.$group = rewriteStageOutputFields(stage.$group);
9631
+ }
9632
+ return next;
9633
+ })
9634
+ : pipeline;
9635
+ return {
9636
+ pipeline: repaired,
9637
+ changed: didAssistantValueChange(pipeline, repaired)
9638
+ };
9639
+ }
9317
9640
  function isMatchExpressionOperand(value) {
9318
9641
  if (typeof value === 'string') {
9319
9642
  return value.startsWith('$$');
@@ -10938,12 +11261,22 @@ function collectAssistantActiveMatchFields(query) {
10938
11261
  var fields = collectMatchFieldsByCondition(query, function (field, condition) { return isAssistantActiveFieldPath(field) && isAssistantActiveCondition(condition); });
10939
11262
  return Array.from(new Set(fields));
10940
11263
  }
10941
- function resolveReadActiveStatusFallback(query, probeDocs) {
11264
+ function resolveReadActiveStatusFallback(query, probeDocs, schemaFields) {
11265
+ var _a;
10942
11266
  var fields = collectAssistantActiveMatchFields(query);
10943
- if (!fields.length || !Array.isArray(probeDocs) || !probeDocs.length) {
11267
+ var hasProbeDocs = Array.isArray(probeDocs) && probeDocs.length > 0;
11268
+ var normalizedSchemaFields = Array.isArray(schemaFields)
11269
+ ? new Set(schemaFields
11270
+ .map(function (field) { return normalizeOptionalString(field).toLowerCase(); })
11271
+ .filter(Boolean)
11272
+ .map(function (field) { return field.split('.').pop() || field; }))
11273
+ : new Set();
11274
+ if (!fields.length || (!hasProbeDocs && !normalizedSchemaFields.size)) {
10944
11275
  return null;
10945
11276
  }
10946
- var hasAnyFieldData = fields.some(function (field) { return hasNonEmptyValue(probeDocs, field, { treatObjectLikeAsEmpty: true }); });
11277
+ var hasAnyFieldData = hasProbeDocs
11278
+ ? fields.some(function (field) { return hasNonEmptyValue(probeDocs, field, { treatObjectLikeAsEmpty: true }); })
11279
+ : false;
10947
11280
  if (hasAnyFieldData) {
10948
11281
  return null;
10949
11282
  }
@@ -10951,6 +11284,38 @@ function resolveReadActiveStatusFallback(query, probeDocs) {
10951
11284
  if (!stripped.changed || !stripped.value || typeof stripped.value !== 'object') {
10952
11285
  return null;
10953
11286
  }
11287
+ var fallbackActiveCandidates = [
11288
+ { field: 'status', condition: { $regex: '^active$', $options: 'i' } },
11289
+ { field: 'state', condition: { $regex: '^active$', $options: 'i' } },
11290
+ { field: 'active', condition: true },
11291
+ { field: 'is_active', condition: true },
11292
+ { field: 'isactive', condition: true },
11293
+ { field: 'enabled', condition: true },
11294
+ { field: 'is_enabled', condition: true },
11295
+ { field: 'isenabled', condition: true }
11296
+ ].filter(function (entry) {
11297
+ if (!entry.field || fields.includes(entry.field)) {
11298
+ return false;
11299
+ }
11300
+ var hasProbeData = hasProbeDocs
11301
+ ? hasNonEmptyValue(probeDocs, entry.field, { treatObjectLikeAsEmpty: true })
11302
+ : false;
11303
+ return hasProbeData || normalizedSchemaFields.has(entry.field);
11304
+ });
11305
+ if (fallbackActiveCandidates.length) {
11306
+ var activeMatch = fallbackActiveCandidates.length === 1
11307
+ ? (_a = {}, _a[fallbackActiveCandidates[0].field] = fallbackActiveCandidates[0].condition, _a) : { $or: fallbackActiveCandidates.map(function (entry) {
11308
+ var _a;
11309
+ return (_a = {}, _a[entry.field] = entry.condition, _a);
11310
+ }) };
11311
+ var baseQuery = stripped.value;
11312
+ return {
11313
+ query: Object.keys(baseQuery).length
11314
+ ? { $and: [baseQuery, activeMatch] }
11315
+ : activeMatch,
11316
+ fields: __spreadArray(__spreadArray([], __read(fields), false), __read(fallbackActiveCandidates.map(function (entry) { return entry.field; })), false)
11317
+ };
11318
+ }
10954
11319
  return {
10955
11320
  query: stripped.value,
10956
11321
  fields: fields
@@ -12159,6 +12524,62 @@ function mergeAssistantHintValues() {
12159
12524
  });
12160
12525
  return result;
12161
12526
  }
12527
+ function hasAssistantDeliveryAliasTerms(value) {
12528
+ var normalized = normalizeOptionalString(value).toLowerCase();
12529
+ if (!normalized) {
12530
+ return false;
12531
+ }
12532
+ return /\b(deliver(?:y|ies)|dispatch|driver|bols?|bills?\s+of\s+lading|pso(?:s)?|production\s+sales\s+orders?|sales\s+orders?|truck[\s_-]+treat(?:ing)?|treater[\s_-]+truck|batch[\s_-]+(?:treat(?:ing)?|jobs?)|specialty[\s_-]+jobs?|continuous|ats|automated[\s_-]+treatment[\s_-]+system|isotanks?|chemical[\s_-]+trailers?|vac[\s_-]+trucks?|assets?|treatment[\s_-]+plans?|treatments?)\b/i.test(normalized);
12533
+ }
12534
+ function hasAssistantDeliveryAliasPathTerms(value) {
12535
+ var normalized = normalizeOptionalString(value).toLowerCase();
12536
+ if (!normalized) {
12537
+ return false;
12538
+ }
12539
+ return /\b(deliver(?:y|ies)?|route|dispatch|driver|bols?|bills?[-_/ ]?of[-_/ ]?lading|pso(?:s)?|production[-_/ ]?sales[-_/ ]?orders?|sales[-_/ ]?orders?|truck[-_/ ]?treat(?:ing)?|treater[-_/ ]?truck|batch[-_/ ]?(?:treat(?:ing)?|jobs?)|specialty[-_/ ]?jobs?|continuous|ats|automated[-_/ ]?treatment[-_/ ]?system|isotanks?|chemical[-_/ ]?trailers?|vac[-_/ ]?trucks?|assets?|treatment[-_/ ]?plans?|treatments?)\b/i.test(normalized);
12540
+ }
12541
+ function hasAssistantPurchaseOrderAliasTerms(value) {
12542
+ var normalized = normalizeOptionalString(value).toLowerCase();
12543
+ if (!normalized) {
12544
+ return false;
12545
+ }
12546
+ return /\b(po(?:s)?|purchase[\s_-]+orders?)\b/i.test(normalized);
12547
+ }
12548
+ function hasAssistantPurchaseOrderAliasPathTerms(value) {
12549
+ var normalized = normalizeOptionalString(value).toLowerCase();
12550
+ if (!normalized) {
12551
+ return false;
12552
+ }
12553
+ return /\b(po(?:s)?|purchase[-_/ ]?orders?)\b/i.test(normalized);
12554
+ }
12555
+ function hasAssistantChemicalCatalogAliasTerms(value) {
12556
+ var normalized = normalizeOptionalString(value).toLowerCase();
12557
+ if (!normalized) {
12558
+ return false;
12559
+ }
12560
+ return /\b(chemicals?|products?|items?)\b/i.test(normalized);
12561
+ }
12562
+ var AI_ASSISTANT_DELIVERY_HINT_CANDIDATES = [
12563
+ 'work-order-dynamics',
12564
+ 'work-orders',
12565
+ 'deliveries',
12566
+ 'jobs',
12567
+ 'treatments',
12568
+ 'treatment-plans',
12569
+ 'assets',
12570
+ 'orders'
12571
+ ];
12572
+ var AI_ASSISTANT_PURCHASE_HINT_CANDIDATES = [
12573
+ 'orders',
12574
+ 'purchase-orders'
12575
+ ];
12576
+ var AI_ASSISTANT_CHEMICAL_HINT_CANDIDATES = [
12577
+ 'chemicals',
12578
+ 'products',
12579
+ 'items',
12580
+ 'inventory',
12581
+ 'blends'
12582
+ ];
12162
12583
  function resolveCollectionHintsFromRoute(route, collectionNames) {
12163
12584
  var normalizedRoute = normalizeOptionalString(route);
12164
12585
  if (!normalizedRoute || !collectionNames.length) {
@@ -12207,6 +12628,15 @@ function resolveAssistantDefaultCollectionHints(message) {
12207
12628
  if (/\busers?\b/.test(text)) {
12208
12629
  push('users');
12209
12630
  }
12631
+ if (hasAssistantDeliveryAliasTerms(text)) {
12632
+ AI_ASSISTANT_DELIVERY_HINT_CANDIDATES.forEach(push);
12633
+ }
12634
+ if (hasAssistantPurchaseOrderAliasTerms(text)) {
12635
+ AI_ASSISTANT_PURCHASE_HINT_CANDIDATES.forEach(push);
12636
+ }
12637
+ if (hasAssistantChemicalCatalogAliasTerms(text)) {
12638
+ AI_ASSISTANT_CHEMICAL_HINT_CANDIDATES.forEach(push);
12639
+ }
12210
12640
  return hints;
12211
12641
  }
12212
12642
  function buildCollectionRankingDebugFromTokens(tokens, collectionNames, max) {
@@ -12469,7 +12899,7 @@ function findBestCollectionMatch(requested, collectionNames) {
12469
12899
  }
12470
12900
  function resolveAssistantCollectionName(db, dbName, requested) {
12471
12901
  return __awaiter(this, void 0, void 0, function () {
12472
- var trimmed, collectionNames, best, candidates;
12902
+ var trimmed, collectionNames, aliasCandidates, matchedAlias, best, candidates;
12473
12903
  return __generator(this, function (_a) {
12474
12904
  switch (_a.label) {
12475
12905
  case 0:
@@ -12483,6 +12913,11 @@ function resolveAssistantCollectionName(db, dbName, requested) {
12483
12913
  if (collectionNames.includes(trimmed)) {
12484
12914
  return [2 /*return*/, { name: trimmed, matched: true, candidates: [], score: 100 }];
12485
12915
  }
12916
+ aliasCandidates = resolveAssistantBridgeCollectionAliasCandidates(trimmed);
12917
+ matchedAlias = aliasCandidates.find(function (candidate) { return collectionNames.includes(candidate); });
12918
+ if (matchedAlias) {
12919
+ return [2 /*return*/, { name: matchedAlias, matched: true, candidates: [], score: 95 }];
12920
+ }
12486
12921
  best = findBestCollectionMatch(trimmed, collectionNames);
12487
12922
  if (best && best.score >= 20) {
12488
12923
  return [2 /*return*/, { name: best.name, matched: true, candidates: [], score: best.score }];
@@ -12500,11 +12935,150 @@ function resolveAssistantCollectionName(db, dbName, requested) {
12500
12935
  }
12501
12936
  var AI_ASSISTANT_BRIDGE_COLLECTION_ALIASES = {
12502
12937
  user: 'users',
12938
+ client: 'customers',
12939
+ clients: 'customers',
12940
+ customer: 'customers',
12941
+ delivery: 'work-order-dynamics',
12942
+ deliveries: 'work-order-dynamics',
12943
+ bol: 'work-order-dynamics',
12944
+ bols: 'work-order-dynamics',
12945
+ billoflading: 'work-order-dynamics',
12946
+ billsoflading: 'work-order-dynamics',
12947
+ pso: 'work-order-dynamics',
12948
+ psos: 'work-order-dynamics',
12949
+ productionsalesorder: 'work-order-dynamics',
12950
+ productionsalesorders: 'work-order-dynamics',
12951
+ salesorder: 'work-order-dynamics',
12952
+ salesorders: 'work-order-dynamics',
12953
+ batchjob: 'jobs',
12954
+ batchjobs: 'jobs',
12955
+ continuous: 'work-order-dynamics',
12956
+ ats: 'work-order-dynamics',
12957
+ automatedtreatmentsystem: 'work-order-dynamics',
12958
+ trucktreat: 'work-order-dynamics',
12959
+ trucktreating: 'work-order-dynamics',
12960
+ treatertruck: 'work-order-dynamics',
12961
+ batchtreat: 'work-order-dynamics',
12962
+ batchtreating: 'work-order-dynamics',
12963
+ specialtyjob: 'work-order-dynamics',
12964
+ specialtyjobs: 'work-order-dynamics',
12965
+ isotank: 'assets',
12966
+ isotanks: 'assets',
12967
+ chemicaltrailer: 'assets',
12968
+ chemicaltrailers: 'assets',
12969
+ vactruck: 'assets',
12970
+ vactrucks: 'assets',
12971
+ asset: 'assets',
12972
+ assets: 'assets',
12973
+ treatmentplan: 'treatment-plans',
12974
+ treatmentplans: 'treatment-plans',
12975
+ treatment: 'treatments',
12976
+ treatments: 'treatments',
12977
+ chemical: 'chemicals',
12978
+ chemicals: 'chemicals',
12979
+ product: 'products',
12980
+ products: 'products',
12981
+ item: 'items',
12982
+ items: 'items',
12983
+ po: 'orders',
12984
+ pos: 'orders',
12985
+ purchaseorder: 'orders',
12986
+ purchaseorders: 'orders',
12503
12987
  supportticket: 'support-tickets',
12504
12988
  supporttickets: 'support-tickets',
12505
12989
  ticket: 'support-tickets',
12506
12990
  tickets: 'support-tickets'
12507
12991
  };
12992
+ var AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES = [
12993
+ 'work-order-dynamics',
12994
+ 'work-orders',
12995
+ 'deliveries',
12996
+ 'jobs',
12997
+ 'treatments',
12998
+ 'treatment-plans',
12999
+ 'assets',
13000
+ 'orders'
13001
+ ];
13002
+ var AI_ASSISTANT_TREATMENT_COLLECTION_ALIAS_CANDIDATES = [
13003
+ 'treatments',
13004
+ 'treatment-plans',
13005
+ 'work-order-dynamics',
13006
+ 'work-orders',
13007
+ 'jobs',
13008
+ 'assets',
13009
+ 'orders'
13010
+ ];
13011
+ var AI_ASSISTANT_ASSET_COLLECTION_ALIAS_CANDIDATES = [
13012
+ 'assets',
13013
+ 'equipment',
13014
+ 'trailers',
13015
+ 'trucks',
13016
+ 'isotanks',
13017
+ 'tanks',
13018
+ 'work-order-dynamics',
13019
+ 'work-orders',
13020
+ 'jobs'
13021
+ ];
13022
+ var AI_ASSISTANT_CHEMICAL_COLLECTION_ALIAS_CANDIDATES = [
13023
+ 'chemicals',
13024
+ 'products',
13025
+ 'items',
13026
+ 'inventory',
13027
+ 'blends',
13028
+ 'orders'
13029
+ ];
13030
+ var AI_ASSISTANT_PURCHASE_COLLECTION_ALIAS_CANDIDATES = [
13031
+ 'orders',
13032
+ 'purchase-orders'
13033
+ ];
13034
+ var AI_ASSISTANT_BRIDGE_COLLECTION_ALIAS_OPTIONS = {
13035
+ delivery: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13036
+ deliveries: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13037
+ bol: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13038
+ bols: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13039
+ billoflading: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13040
+ billsoflading: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13041
+ pso: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13042
+ psos: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13043
+ productionsalesorder: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13044
+ productionsalesorders: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13045
+ salesorder: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13046
+ salesorders: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13047
+ trucktreat: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13048
+ trucktreating: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13049
+ treatertruck: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13050
+ batchtreat: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13051
+ batchtreating: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13052
+ batchjob: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13053
+ batchjobs: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13054
+ specialtyjob: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13055
+ specialtyjobs: AI_ASSISTANT_DELIVERY_COLLECTION_ALIAS_CANDIDATES,
13056
+ continuous: AI_ASSISTANT_TREATMENT_COLLECTION_ALIAS_CANDIDATES,
13057
+ ats: AI_ASSISTANT_TREATMENT_COLLECTION_ALIAS_CANDIDATES,
13058
+ automatedtreatmentsystem: AI_ASSISTANT_TREATMENT_COLLECTION_ALIAS_CANDIDATES,
13059
+ treatmentplan: AI_ASSISTANT_TREATMENT_COLLECTION_ALIAS_CANDIDATES,
13060
+ treatmentplans: AI_ASSISTANT_TREATMENT_COLLECTION_ALIAS_CANDIDATES,
13061
+ treatment: AI_ASSISTANT_TREATMENT_COLLECTION_ALIAS_CANDIDATES,
13062
+ treatments: AI_ASSISTANT_TREATMENT_COLLECTION_ALIAS_CANDIDATES,
13063
+ asset: AI_ASSISTANT_ASSET_COLLECTION_ALIAS_CANDIDATES,
13064
+ assets: AI_ASSISTANT_ASSET_COLLECTION_ALIAS_CANDIDATES,
13065
+ isotank: AI_ASSISTANT_ASSET_COLLECTION_ALIAS_CANDIDATES,
13066
+ isotanks: AI_ASSISTANT_ASSET_COLLECTION_ALIAS_CANDIDATES,
13067
+ chemicaltrailer: AI_ASSISTANT_ASSET_COLLECTION_ALIAS_CANDIDATES,
13068
+ chemicaltrailers: AI_ASSISTANT_ASSET_COLLECTION_ALIAS_CANDIDATES,
13069
+ vactruck: AI_ASSISTANT_ASSET_COLLECTION_ALIAS_CANDIDATES,
13070
+ vactrucks: AI_ASSISTANT_ASSET_COLLECTION_ALIAS_CANDIDATES,
13071
+ chemical: AI_ASSISTANT_CHEMICAL_COLLECTION_ALIAS_CANDIDATES,
13072
+ chemicals: AI_ASSISTANT_CHEMICAL_COLLECTION_ALIAS_CANDIDATES,
13073
+ product: AI_ASSISTANT_CHEMICAL_COLLECTION_ALIAS_CANDIDATES,
13074
+ products: AI_ASSISTANT_CHEMICAL_COLLECTION_ALIAS_CANDIDATES,
13075
+ item: AI_ASSISTANT_CHEMICAL_COLLECTION_ALIAS_CANDIDATES,
13076
+ items: AI_ASSISTANT_CHEMICAL_COLLECTION_ALIAS_CANDIDATES,
13077
+ po: AI_ASSISTANT_PURCHASE_COLLECTION_ALIAS_CANDIDATES,
13078
+ pos: AI_ASSISTANT_PURCHASE_COLLECTION_ALIAS_CANDIDATES,
13079
+ purchaseorder: AI_ASSISTANT_PURCHASE_COLLECTION_ALIAS_CANDIDATES,
13080
+ purchaseorders: AI_ASSISTANT_PURCHASE_COLLECTION_ALIAS_CANDIDATES
13081
+ };
12508
13082
  var AI_ASSISTANT_DIRECT_COLLECTION_FALLBACK_ALLOWLIST = new Set([]);
12509
13083
  var AI_ASSISTANT_SUPPORT_COLLECTION_FALLBACKS = [
12510
13084
  'support-tickets',
@@ -12571,9 +13145,8 @@ function resolveAssistantCrossCollectionFallbackCandidates(collection) {
12571
13145
  }
12572
13146
  candidates.add(candidate);
12573
13147
  };
12574
- var alias = resolveAssistantBridgeCollectionAlias(normalized)
12575
- || resolveAssistantBridgeCollectionAlias(normalizeCollectionKey(normalized));
12576
- addCandidate(alias);
13148
+ var aliasCandidates = mergeAssistantHintValues(resolveAssistantBridgeCollectionAliasCandidates(normalized), resolveAssistantBridgeCollectionAliasCandidates(normalizeCollectionKey(normalized)));
13149
+ aliasCandidates.forEach(addCandidate);
12577
13150
  if (AI_ASSISTANT_SUPPORT_COLLECTION_FALLBACKS.includes(normalized)
12578
13151
  || normalized.includes('ticket')
12579
13152
  || normalized.includes('support')) {
@@ -12639,6 +13212,123 @@ function resolveAssistantAvailableCrossCollectionFallbacks(db, dbName, collectio
12639
13212
  });
12640
13213
  });
12641
13214
  }
13215
+ var AI_ASSISTANT_FALLBACK_DIMENSION_EMPTY_VALUES = new Set([
13216
+ '',
13217
+ '-',
13218
+ '--',
13219
+ 'n/a',
13220
+ 'na',
13221
+ 'none',
13222
+ 'null',
13223
+ 'unknown',
13224
+ '(unknown)',
13225
+ 'not set',
13226
+ 'unassigned'
13227
+ ]);
13228
+ function isAssistantNumericLikeValue(value) {
13229
+ if (typeof value === 'number') {
13230
+ return Number.isFinite(value);
13231
+ }
13232
+ if (typeof value !== 'string') {
13233
+ return false;
13234
+ }
13235
+ var trimmed = value.trim();
13236
+ if (!trimmed) {
13237
+ return false;
13238
+ }
13239
+ var normalized = trimmed
13240
+ .replace(/[$,%\s]/g, '')
13241
+ .replace(/,/g, '');
13242
+ return /^[-+]?\d+(\.\d+)?$/.test(normalized);
13243
+ }
13244
+ function isAssistantDateLikeValue(value) {
13245
+ if (value instanceof Date) {
13246
+ return !Number.isNaN(value.getTime());
13247
+ }
13248
+ if (typeof value !== 'string') {
13249
+ return false;
13250
+ }
13251
+ var trimmed = value.trim();
13252
+ if (!trimmed || trimmed.length < 8) {
13253
+ return false;
13254
+ }
13255
+ if (!/[-/]/.test(trimmed)) {
13256
+ return false;
13257
+ }
13258
+ var parsed = new Date(trimmed);
13259
+ return !Number.isNaN(parsed.getTime());
13260
+ }
13261
+ function isAssistantNonEmptyDimensionValue(value) {
13262
+ if (value === null || value === undefined) {
13263
+ return false;
13264
+ }
13265
+ if (typeof value === 'string') {
13266
+ var normalized = value.trim().toLowerCase();
13267
+ return normalized ? !AI_ASSISTANT_FALLBACK_DIMENSION_EMPTY_VALUES.has(normalized) : false;
13268
+ }
13269
+ if (typeof value === 'number') {
13270
+ return Number.isFinite(value);
13271
+ }
13272
+ if (typeof value === 'boolean') {
13273
+ return true;
13274
+ }
13275
+ if (value instanceof Date) {
13276
+ return !Number.isNaN(value.getTime());
13277
+ }
13278
+ if (isMongoObjectId(value)) {
13279
+ return true;
13280
+ }
13281
+ return true;
13282
+ }
13283
+ function resolveAssistantFallbackDimensionFields(documents) {
13284
+ var docs = Array.isArray(documents) ? documents : [];
13285
+ var keys = new Set();
13286
+ docs.forEach(function (doc) {
13287
+ if (!doc || typeof doc !== 'object' || Array.isArray(doc)) {
13288
+ return;
13289
+ }
13290
+ Object.keys(doc).forEach(function (key) {
13291
+ if (key && key !== '_id') {
13292
+ keys.add(key);
13293
+ }
13294
+ });
13295
+ });
13296
+ var dimensions = [];
13297
+ Array.from(keys).forEach(function (key) {
13298
+ var values = docs
13299
+ .map(function (doc) { return (doc && typeof doc === 'object' ? doc[key] : undefined); })
13300
+ .filter(function (value) { return value !== null && value !== undefined; });
13301
+ if (!values.length) {
13302
+ dimensions.push(key);
13303
+ return;
13304
+ }
13305
+ var allNumericLike = values.every(function (value) { return isAssistantNumericLikeValue(value); });
13306
+ if (allNumericLike) {
13307
+ return;
13308
+ }
13309
+ var allDateLike = values.every(function (value) { return isAssistantDateLikeValue(value); });
13310
+ if (allDateLike) {
13311
+ return;
13312
+ }
13313
+ dimensions.push(key);
13314
+ });
13315
+ return dimensions;
13316
+ }
13317
+ function shouldAcceptAssistantFallbackDocuments(documents) {
13318
+ var docs = Array.isArray(documents)
13319
+ ? documents.filter(function (doc) { return doc && typeof doc === 'object' && !Array.isArray(doc); })
13320
+ : [];
13321
+ if (!docs.length) {
13322
+ return false;
13323
+ }
13324
+ var dimensionFields = resolveAssistantFallbackDimensionFields(docs);
13325
+ if (!dimensionFields.length) {
13326
+ return true;
13327
+ }
13328
+ return docs.some(function (doc) {
13329
+ return dimensionFields.some(function (field) { return isAssistantNonEmptyDimensionValue(doc[field]); });
13330
+ });
13331
+ }
12642
13332
  function collectAggregateReferencedFieldPaths(pipeline) {
12643
13333
  var fields = new Set();
12644
13334
  (pipeline || []).forEach(function (stage) {
@@ -12773,10 +13463,7 @@ function resolveAssistantNestedPrefixCollectionCandidates(params) {
12773
13463
  }
12774
13464
  candidates.push(preferred);
12775
13465
  };
12776
- var alias = resolveAssistantBridgeCollectionAlias(normalizedPrefix);
12777
- if (alias) {
12778
- push(alias);
12779
- }
13466
+ resolveAssistantBridgeCollectionAliasCandidates(normalizedPrefix).forEach(push);
12780
13467
  push(normalizedPrefix);
12781
13468
  resolveAssistantAvailableCrossCollectionFallbacksFromNames(normalizedPrefix, params.triedCollections, params.collectionNames).forEach(push);
12782
13469
  var tokenizedPrefix = tokenizeCollectionText(normalizedPrefix);
@@ -12864,9 +13551,25 @@ function resolveAssistantNestedAggregateFallbacks(params) {
12864
13551
  });
12865
13552
  });
12866
13553
  }
12867
- function resolveAssistantBridgeCollectionAlias(value) {
13554
+ function resolveAssistantBridgeCollectionAliasCandidates(value) {
12868
13555
  var key = normalizeCollectionKey(value);
12869
- return AI_ASSISTANT_BRIDGE_COLLECTION_ALIASES[key] || '';
13556
+ if (!key) {
13557
+ return [];
13558
+ }
13559
+ var candidates = [];
13560
+ var push = function (candidate) {
13561
+ var normalized = normalizeOptionalString(candidate);
13562
+ if (!normalized || candidates.includes(normalized)) {
13563
+ return;
13564
+ }
13565
+ candidates.push(normalized);
13566
+ };
13567
+ var aliasOptions = AI_ASSISTANT_BRIDGE_COLLECTION_ALIAS_OPTIONS[key];
13568
+ if (Array.isArray(aliasOptions)) {
13569
+ aliasOptions.forEach(push);
13570
+ }
13571
+ push(AI_ASSISTANT_BRIDGE_COLLECTION_ALIASES[key]);
13572
+ return candidates;
12870
13573
  }
12871
13574
  function isAssistantDirectCollectionFallbackAllowed(collection) {
12872
13575
  var normalized = normalizeOptionalString(collection);
@@ -12903,7 +13606,7 @@ function doesAssistantCollectionExistInDb(db, collection) {
12903
13606
  }
12904
13607
  function resolveAssistantReportBuilderBridgeCollection(collection_1, db_1) {
12905
13608
  return __awaiter(this, arguments, void 0, function (collection, db, dbName) {
12906
- var normalized, alias, manager, hasManager, candidates, pushCandidate, base, reportCandidate, candidates_5, candidates_5_1, candidate, model, resolved, resolvedName, resolvedModel, _a, candidates_6, candidates_6_1, candidate, e_34_1, candidates_7, candidates_7_1, candidate;
13609
+ var normalized, aliasCandidates, alias, manager, hasManager, candidates, pushCandidate, base, reportCandidate, candidates_5, candidates_5_1, candidate, model, resolved, resolvedName, resolvedModel, _a, candidates_6, candidates_6_1, candidate, e_34_1, candidates_7, candidates_7_1, candidate;
12907
13610
  var e_35, _b, e_34, _c, e_36, _d;
12908
13611
  var _e;
12909
13612
  if (dbName === void 0) { dbName = ''; }
@@ -12914,7 +13617,8 @@ function resolveAssistantReportBuilderBridgeCollection(collection_1, db_1) {
12914
13617
  if (!normalized) {
12915
13618
  throw new Error('AI assistant report builder bridge: Collection is required.');
12916
13619
  }
12917
- alias = resolveAssistantBridgeCollectionAlias(normalized);
13620
+ aliasCandidates = resolveAssistantBridgeCollectionAliasCandidates(normalized);
13621
+ alias = aliasCandidates[0] || '';
12918
13622
  manager = (_e = resolveio_server_app_1.ResolveIOServer.getMongoManager) === null || _e === void 0 ? void 0 : _e.call(resolveio_server_app_1.ResolveIOServer);
12919
13623
  hasManager = !!(manager && typeof manager.collection === 'function');
12920
13624
  candidates = [];
@@ -12926,9 +13630,7 @@ function resolveAssistantReportBuilderBridgeCollection(collection_1, db_1) {
12926
13630
  candidates.push(value);
12927
13631
  };
12928
13632
  pushCandidate(normalized);
12929
- if (alias) {
12930
- pushCandidate(alias);
12931
- }
13633
+ aliasCandidates.forEach(pushCandidate);
12932
13634
  base = stripVersionSuffix(normalized.startsWith('report-') ? normalized.slice('report-'.length) : normalized);
12933
13635
  if (base && base !== normalized) {
12934
13636
  pushCandidate(base);
@@ -14071,6 +14773,8 @@ function buildAssistantWorkspaceRootCandidates(params) {
14071
14773
  var pathCandidates = [
14072
14774
  serverConfig['AI_ASSISTANT_WORKSPACE_ROOT'],
14073
14775
  env['AI_ASSISTANT_WORKSPACE_ROOT'],
14776
+ serverConfig['AI_ASSISTANT_ROOT_WORKSPACE'],
14777
+ env['AI_ASSISTANT_ROOT_WORKSPACE'],
14074
14778
  serverConfig['AI_TERMINAL_WORKSPACE_ROOT'],
14075
14779
  env['AI_TERMINAL_WORKSPACE_ROOT'],
14076
14780
  serverConfig['AI_DASHBOARD_WORKSPACE_ROOT'],
@@ -14268,7 +14972,7 @@ var AI_ASSISTANT_BUG_ISSUE_PATTERNS = [
14268
14972
  /\bbug\b/,
14269
14973
  /\bissue\b/,
14270
14974
  /\berror\b/,
14271
- /\bexception\b/,
14975
+ /\bexception\b(?!\s+list\b)/,
14272
14976
  /\bfail(?:ed|ing|ure)?\b/,
14273
14977
  /\bbroken\b/,
14274
14978
  /\bnot working\b/,
@@ -14375,6 +15079,7 @@ function normalizeAssistantPlannerIntentType(value) {
14375
15079
  function classifyAssistantRequestByHeuristics(message) {
14376
15080
  var isData = isAssistantDataQuestion(message);
14377
15081
  var isNavigation = isAssistantNavigationQuestion(message);
15082
+ var isChangeHistory = isAssistantChangeHistoryQuestion(message);
14378
15083
  var isBug = isAssistantBugIssueQuestion(message);
14379
15084
  var isFeatureInfo = isAssistantFeatureInfoQuestion(message);
14380
15085
  var type = 'unknown';
@@ -14387,6 +15092,9 @@ function classifyAssistantRequestByHeuristics(message) {
14387
15092
  else if (isNavigation) {
14388
15093
  type = 'navigation';
14389
15094
  }
15095
+ else if (isChangeHistory) {
15096
+ type = 'feature_info';
15097
+ }
14390
15098
  else if (isBug) {
14391
15099
  type = 'bug_issue';
14392
15100
  }
@@ -14478,8 +15186,8 @@ function hasAssistantDatedLanguage(message) {
14478
15186
  /\b(over|across)\s+time\b/i,
14479
15187
  /\btime\s*series\b/i,
14480
15188
  /\btrend(?:ing|s)?\b/i,
14481
- /\b(last|past|previous|recent)\s+(?:\d+|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve)\s+(day|week|month|quarter|year)s?\b/i,
14482
- /\bover\s+the\s+last\s+(?:\d+|one|two|three|four|five|six|seven|eight|nine|ten|eleven|twelve)\s+(day|week|month|quarter|year)s?\b/i,
15189
+ /\b(daily|weekly|monthly|quarterly|yearly)\b/i,
15190
+ /\b(each|every)\s+(day|week|month|quarter|year)\b/i,
14483
15191
  /\bmonth\s+over\s+month\b/i,
14484
15192
  /\bquarter\s+over\s+quarter\b/i,
14485
15193
  /\byear\s+over\s+year\b/i
@@ -14680,14 +15388,25 @@ function shouldPreferAssistantListDirective(message, plannerOutput, requestClass
14680
15388
  }
14681
15389
  return hasListVerb && (hasLimitCue || hasWindowCue);
14682
15390
  }
15391
+ function isAssistantTemporalGroupByValue(value) {
15392
+ var normalized = normalizeOptionalString(value).toLowerCase();
15393
+ return normalized === 'day'
15394
+ || normalized === 'week'
15395
+ || normalized === 'month'
15396
+ || normalized === 'quarter'
15397
+ || normalized === 'year'
15398
+ || normalized === 'date';
15399
+ }
14683
15400
  function shouldEnforceAssistantDatedDirective(message, plannerOutput, requestClassification) {
15401
+ var _a, _b;
14684
15402
  if (!(requestClassification === null || requestClassification === void 0 ? void 0 : requestClassification.dataQuestion)) {
14685
15403
  return false;
14686
15404
  }
14687
15405
  if (shouldPreferAssistantListDirective(message, plannerOutput, requestClassification)) {
14688
15406
  return false;
14689
15407
  }
14690
- if (resolveAssistantRequestedTimeGrain(message, plannerOutput)) {
15408
+ var plannerGroupBy = normalizeOptionalString((_b = (_a = plannerOutput === null || plannerOutput === void 0 ? void 0 : plannerOutput.dataPlan) === null || _a === void 0 ? void 0 : _a.queryPlan) === null || _b === void 0 ? void 0 : _b.groupBy);
15409
+ if (isAssistantTemporalGroupByValue(plannerGroupBy)) {
14691
15410
  return true;
14692
15411
  }
14693
15412
  return hasAssistantDatedLanguage(message);
@@ -15606,16 +16325,16 @@ function resolveAssistantChangeModulesFromText(message) {
15606
16325
  if (/\b(invoice|invoices|invoicing|revenue|billing|payment|payments|paid)\b/i.test(text)) {
15607
16326
  push('invoice');
15608
16327
  }
15609
- if (/\b(work[\s-]*order|wo)\b/i.test(text)) {
16328
+ if (/\b(work[\s-]*order|wo)\b/i.test(text) || hasAssistantPurchaseOrderAliasTerms(text)) {
15610
16329
  push('work_order');
15611
16330
  }
15612
- if (/\b(deliver(?:y|ies)|route|dispatch|driver)\b/i.test(text)) {
16331
+ if (/\broute\b/i.test(text) || hasAssistantDeliveryAliasTerms(text)) {
15613
16332
  push('delivery');
15614
16333
  }
15615
16334
  if (/\b(blend|blending)\b/i.test(text)) {
15616
16335
  push('blend');
15617
16336
  }
15618
- if (/\b(chemical|chemicals)\b/i.test(text)) {
16337
+ if (hasAssistantChemicalCatalogAliasTerms(text)) {
15619
16338
  push('chemical');
15620
16339
  }
15621
16340
  if (/\b(job|jobs)\b/i.test(text)) {
@@ -15643,16 +16362,16 @@ function resolveAssistantChangeModulesFromPath(filePath) {
15643
16362
  if (/\binvoices?\b/.test(normalized)) {
15644
16363
  push('invoice');
15645
16364
  }
15646
- if (/\bwork[-_/ ]?order|wo[-_/ ]|orders?\b/.test(normalized)) {
16365
+ if (/\bwork[-_/ ]?order|wo[-_/ ]|orders?\b/.test(normalized) || hasAssistantPurchaseOrderAliasPathTerms(normalized)) {
15647
16366
  push('work_order');
15648
16367
  }
15649
- if (/\bdeliver|route|dispatch|driver\b/.test(normalized)) {
16368
+ if (hasAssistantDeliveryAliasPathTerms(normalized)) {
15650
16369
  push('delivery');
15651
16370
  }
15652
16371
  if (/\bblend\b/.test(normalized)) {
15653
16372
  push('blend');
15654
16373
  }
15655
- if (/\bchemical\b/.test(normalized)) {
16374
+ if (/\b(chemical|product|item)\b/.test(normalized)) {
15656
16375
  push('chemical');
15657
16376
  }
15658
16377
  if (/\bjobs?\b/.test(normalized)) {
@@ -15684,13 +16403,13 @@ function userHasAssistantChangeModuleAccess(user, module) {
15684
16403
  case 'invoice':
15685
16404
  return userHasInvoiceAccess(user);
15686
16405
  case 'work_order':
15687
- return userHasViewTokenPermission(user, /work[-_/ ]?order|dispatch|operations|field|delivery|route/i);
16406
+ return userHasViewTokenPermission(user, /work[-_/ ]?order|dispatch|operations|field|delivery|route|bol|pso|sales[-_/ ]?order|purchase[-_/ ]?order|\bpo\b|\bpos\b|continuous|ats|treat(?:ment|ing)|asset/i);
15688
16407
  case 'delivery':
15689
- return userHasViewTokenPermission(user, /delivery|route|dispatch|work[-_/ ]?order/i);
16408
+ return userHasViewTokenPermission(user, /delivery|route|dispatch|work[-_/ ]?order|bol|pso|sales[-_/ ]?order|truck[-_/ ]?treat(?:ing)?|treater|specialty|batch[-_/ ]?(?:treat(?:ing)?|job)|continuous|ats|automated[-_/ ]?treatment[-_/ ]?system|isotank|chemical[-_/ ]?trailer|vac[-_/ ]?truck|asset|treatment[-_/ ]?plan|treatments?/i);
15690
16409
  case 'blend':
15691
16410
  return userHasViewTokenPermission(user, /blend|chemical|mix/i);
15692
16411
  case 'chemical':
15693
- return userHasViewTokenPermission(user, /chemical|blend/i);
16412
+ return userHasViewTokenPermission(user, /chemical|blend|product|item|inventory/i);
15694
16413
  case 'job':
15695
16414
  return userHasViewTokenPermission(user, /job|work[-_/ ]?order/i);
15696
16415
  case 'portal':
@@ -15962,6 +16681,8 @@ function parseAssistantGitLogOutput(raw) {
15962
16681
  function buildAssistantChangeHistorySummaryFromCommits(params) {
15963
16682
  var message = normalizeOptionalString(params.message);
15964
16683
  var branch = normalizeOptionalString(params.branch);
16684
+ var repositoryName = normalizeOptionalString(params.repositoryName).toLowerCase();
16685
+ var isLibraryRepository = /(?:^|[-_/])(resolveio[-_/])?(server[-_/]?lib|client[-_/]?lib)(?:$|[-_/])/i.test(repositoryName);
15965
16686
  var now = params.now instanceof Date && !Number.isNaN(params.now.getTime()) ? params.now : new Date();
15966
16687
  var commits = Array.isArray(params.commits) ? params.commits : [];
15967
16688
  var requestedModules = resolveAssistantChangeModulesFromText(message);
@@ -16010,6 +16731,10 @@ function buildAssistantChangeHistorySummaryFromCommits(params) {
16010
16731
  }
16011
16732
  topCommits.forEach(function (commit) {
16012
16733
  var dateText = formatAssistantChangeDate(commit.date) || 'recent';
16734
+ if (isLibraryRepository) {
16735
+ lines.push("- ".concat(dateText, ": Platform/library update."));
16736
+ return;
16737
+ }
16013
16738
  lines.push("- ".concat(dateText, ": ").concat(sanitizeAssistantChangeSubject(commit.subject), "."));
16014
16739
  });
16015
16740
  if (asksDuration) {
@@ -16032,9 +16757,29 @@ function buildAssistantChangeHistorySummaryFromCommits(params) {
16032
16757
  }
16033
16758
  return __assign({ response: lines.join('\n'), reason: 'detailed', commitCount: topCommits.length, generic: false }, (branch ? { branch: branch } : {}));
16034
16759
  }
16760
+ function buildAssistantChangeHistoryUnavailableResponse(message, reason) {
16761
+ var asksDuration = isAssistantChangeDurationQuestion(message);
16762
+ var lines = ['Recent change summary:'];
16763
+ if (reason === 'error') {
16764
+ lines.push('- I could not read repository history in this environment right now, so exact rollout dates are unavailable.');
16765
+ }
16766
+ else {
16767
+ lines.push('- Repository history is not accessible in this environment, so exact rollout dates are unavailable here.');
16768
+ }
16769
+ lines.push('- I can still explain current behavior now, and provide exact dates once repository history is available.');
16770
+ if (asksDuration) {
16771
+ lines.push('- Best-known timing: unable to confirm exact first release date from this runtime.');
16772
+ }
16773
+ return {
16774
+ response: lines.join('\n'),
16775
+ reason: reason,
16776
+ commitCount: 0,
16777
+ generic: true
16778
+ };
16779
+ }
16035
16780
  function resolveAssistantChangeHistoryFastPathResponse(params) {
16036
16781
  return __awaiter(this, void 0, void 0, function () {
16037
- var workspaceRoot, _a, gitRoots, sawExecutionError, gitRoots_1, gitRoots_1_1, gitRoot, _b, branch, _c, _d, limit, historyDepth, rawHistory, commits, _e, e_46_1;
16782
+ var workspaceRoot, _a, gitRoots, featureKeywords, sawExecutionError, bestFallback, gitRoots_1, gitRoots_1_1, gitRoot, _b, branch, _c, _d, limit, historyDepth, rawHistory, commits, summary, hasKeywordMatches, _e, e_46_1;
16038
16783
  var e_46, _f;
16039
16784
  return __generator(this, function (_g) {
16040
16785
  switch (_g.label) {
@@ -16056,15 +16801,17 @@ function resolveAssistantChangeHistoryFastPathResponse(params) {
16056
16801
  return [3 /*break*/, 4];
16057
16802
  case 4:
16058
16803
  if (!workspaceRoot) {
16059
- return [2 /*return*/, null];
16804
+ return [2 /*return*/, buildAssistantChangeHistoryUnavailableResponse(params.message, 'no_repo')];
16060
16805
  }
16061
16806
  return [4 /*yield*/, resolveAssistantWorkspaceGitRoots(workspaceRoot)];
16062
16807
  case 5:
16063
16808
  gitRoots = _g.sent();
16064
16809
  if (!gitRoots.length) {
16065
- return [2 /*return*/, null];
16810
+ return [2 /*return*/, buildAssistantChangeHistoryUnavailableResponse(params.message, 'no_repo')];
16066
16811
  }
16812
+ featureKeywords = resolveAssistantChangeHistoryKeywords(params.message);
16067
16813
  sawExecutionError = false;
16814
+ bestFallback = null;
16068
16815
  _g.label = 6;
16069
16816
  case 6:
16070
16817
  _g.trys.push([6, 21, 22, 23]);
@@ -16121,13 +16868,31 @@ function resolveAssistantChangeHistoryFastPathResponse(params) {
16121
16868
  if (!commits.length) {
16122
16869
  return [3 /*break*/, 19];
16123
16870
  }
16124
- return [2 /*return*/, buildAssistantChangeHistorySummaryFromCommits({
16125
- message: params.message,
16126
- user: params.user,
16127
- isSuperAdmin: params.isSuperAdmin,
16128
- commits: commits,
16129
- branch: branch
16130
- })];
16871
+ summary = buildAssistantChangeHistorySummaryFromCommits({
16872
+ message: params.message,
16873
+ user: params.user,
16874
+ isSuperAdmin: params.isSuperAdmin,
16875
+ commits: commits,
16876
+ branch: branch,
16877
+ repositoryName: path.basename(gitRoot)
16878
+ });
16879
+ hasKeywordMatches = !featureKeywords.length
16880
+ || commits.some(function (commit) { return scoreAssistantChangeHistoryCommitByKeywords(commit, featureKeywords) > 0; });
16881
+ if (hasKeywordMatches && summary.reason === 'detailed') {
16882
+ return [2 /*return*/, summary];
16883
+ }
16884
+ if (!bestFallback) {
16885
+ bestFallback = summary;
16886
+ return [3 /*break*/, 19];
16887
+ }
16888
+ if (summary.reason === 'detailed' && bestFallback.reason !== 'detailed') {
16889
+ bestFallback = summary;
16890
+ return [3 /*break*/, 19];
16891
+ }
16892
+ if (summary.reason === bestFallback.reason && summary.commitCount > bestFallback.commitCount) {
16893
+ bestFallback = summary;
16894
+ }
16895
+ return [3 /*break*/, 19];
16131
16896
  case 18:
16132
16897
  _e = _g.sent();
16133
16898
  sawExecutionError = true;
@@ -16147,10 +16912,13 @@ function resolveAssistantChangeHistoryFastPathResponse(params) {
16147
16912
  finally { if (e_46) throw e_46.error; }
16148
16913
  return [7 /*endfinally*/];
16149
16914
  case 23:
16915
+ if (bestFallback) {
16916
+ return [2 /*return*/, bestFallback];
16917
+ }
16150
16918
  if (sawExecutionError) {
16151
- return [2 /*return*/, null];
16919
+ return [2 /*return*/, buildAssistantChangeHistoryUnavailableResponse(params.message, 'error')];
16152
16920
  }
16153
- return [2 /*return*/, null];
16921
+ return [2 /*return*/, buildAssistantChangeHistoryUnavailableResponse(params.message, 'no_repo')];
16154
16922
  }
16155
16923
  });
16156
16924
  });