@resolveio/server-lib 22.1.9 → 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.
@@ -352,8 +352,59 @@ var AI_ASSISTANT_COLLECTION_DOMAIN_TOKENS = new Set([
352
352
  'orders',
353
353
  'delivery',
354
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',
355
397
  'truck',
398
+ 'trucktreat',
399
+ 'trucktreating',
400
+ 'product',
401
+ 'products',
402
+ 'item',
403
+ 'items',
404
+ 'inventory',
356
405
  'treating',
406
+ 'batchtreat',
407
+ 'batchtreating',
357
408
  'route',
358
409
  'routes',
359
410
  'well',
@@ -403,6 +454,21 @@ var AI_ASSISTANT_TERM_SYNONYMS = [
403
454
  label: 'support tickets',
404
455
  pattern: /\bsupport[\s-]*tickets?\b/i,
405
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']
406
472
  }
407
473
  ];
408
474
  var AI_ASSISTANT_REPORT_BUILDER_EXPERT_PLAYBOOK = [
@@ -2243,6 +2309,7 @@ function executeAiAssistantCodexRun(payload, context) {
2243
2309
  case 45:
2244
2310
  _j = _13.sent();
2245
2311
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
2312
+ assistantContent = applyAssistantDisplayTableToResponse(assistantContent, toolPayload.result.output.display);
2246
2313
  return [3 /*break*/, 46];
2247
2314
  case 46: return [3 /*break*/, 48];
2248
2315
  case 47:
@@ -2549,7 +2616,7 @@ function executeAiAssistantReportIssue(payload, context) {
2549
2616
  }
2550
2617
  function executeAiAssistantMongoRead(payload, context) {
2551
2618
  return __awaiter(this, void 0, void 0, function () {
2552
- 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, 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;
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;
2553
2620
  var e_1, _p;
2554
2621
  var _this = this;
2555
2622
  var _q, _r;
@@ -2845,7 +2912,7 @@ function executeAiAssistantMongoRead(payload, context) {
2845
2912
  _s.label = 24;
2846
2913
  case 24:
2847
2914
  probeDocs = _e;
2848
- activeFallback = resolveReadActiveStatusFallback(executedQuery, probeDocs || []);
2915
+ activeFallback = resolveReadActiveStatusFallback(executedQuery, probeDocs || [], schemaFields);
2849
2916
  if (!activeFallback) return [3 /*break*/, 26];
2850
2917
  fallbackMeta.activeStatus = {
2851
2918
  fields: activeFallback.fields,
@@ -2934,7 +3001,8 @@ function executeAiAssistantMongoRead(payload, context) {
2934
3001
  }
2935
3002
  _s.label = 34;
2936
3003
  case 34:
2937
- if (!(!documents.length && crossCollectionRetryEnabled)) return [3 /*break*/, 43];
3004
+ hasActiveStatusFilters = collectAssistantActiveMatchFields(executedQuery).length > 0;
3005
+ if (!(!documents.length && crossCollectionRetryEnabled && !hasActiveStatusFilters)) return [3 /*break*/, 44];
2938
3006
  return [4 /*yield*/, resolveAssistantAvailableCrossCollectionFallbacks(db, dbName, collection, triedCollections)];
2939
3007
  case 35:
2940
3008
  crossCollectionCandidates = _s.sent();
@@ -3003,8 +3071,20 @@ function executeAiAssistantMongoRead(payload, context) {
3003
3071
  }
3004
3072
  finally { if (e_1) throw e_1.error; }
3005
3073
  return [7 /*endfinally*/];
3006
- case 43:
3007
- 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];
3008
3088
  nameFields = collectMatchFieldsByCondition(executedQuery, function (field, condition) { return isRegexMatchCondition(condition)
3009
3089
  || (typeof condition === 'string' && shouldApplyAssistantNameRegex(field)); });
3010
3090
  dateFields = collectMatchFieldsByCondition(executedQuery, function (_field, condition) { return isDateCondition(condition); });
@@ -3012,36 +3092,36 @@ function executeAiAssistantMongoRead(payload, context) {
3012
3092
  nameFields: nameFields.length ? nameFields : undefined,
3013
3093
  dateFields: dateFields.length ? dateFields : undefined
3014
3094
  };
3015
- _s.label = 44;
3016
- case 44:
3017
- _s.trys.push([44, 49, , 50]);
3018
- 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];
3019
3099
  queryNoName = stripMatchFields(executedQuery, nameFields);
3020
3100
  _g = diagnostics;
3021
3101
  return [4 /*yield*/, db.collection(collection).countDocuments(queryNoName, {
3022
3102
  readPreference: AI_ASSISTANT_READ_PREFERENCE
3023
3103
  })];
3024
- case 45:
3104
+ case 47:
3025
3105
  _g.recentCount = _s.sent();
3026
- _s.label = 46;
3027
- case 46:
3028
- if (!dateFields.length) return [3 /*break*/, 48];
3106
+ _s.label = 48;
3107
+ case 48:
3108
+ if (!dateFields.length) return [3 /*break*/, 50];
3029
3109
  queryNoDate = stripMatchFields(executedQuery, dateFields);
3030
3110
  _h = diagnostics;
3031
3111
  return [4 /*yield*/, db.collection(collection).countDocuments(queryNoDate, {
3032
3112
  readPreference: AI_ASSISTANT_READ_PREFERENCE
3033
3113
  })];
3034
- case 47:
3035
- _h.nameMatchCount = _s.sent();
3036
- _s.label = 48;
3037
- case 48: return [3 /*break*/, 50];
3038
3114
  case 49:
3115
+ _h.nameMatchCount = _s.sent();
3116
+ _s.label = 50;
3117
+ case 50: return [3 /*break*/, 52];
3118
+ case 51:
3039
3119
  _j = _s.sent();
3040
- return [3 /*break*/, 50];
3041
- case 50:
3042
- _s.trys.push([50, 53, , 54]);
3120
+ return [3 /*break*/, 52];
3121
+ case 52:
3122
+ _s.trys.push([52, 55, , 56]);
3043
3123
  _k = probeDocs;
3044
- if (_k) return [3 /*break*/, 52];
3124
+ if (_k) return [3 /*break*/, 54];
3045
3125
  return [4 /*yield*/, fetchAssistantProbeDocs({
3046
3126
  db: db,
3047
3127
  collection: collection,
@@ -3050,56 +3130,56 @@ function executeAiAssistantMongoRead(payload, context) {
3050
3130
  isSuperAdmin: isSuperAdmin,
3051
3131
  includeClientScope: shouldScopeByClient
3052
3132
  })];
3053
- case 51:
3133
+ case 53:
3054
3134
  _k = (_s.sent());
3055
- _s.label = 52;
3056
- case 52:
3135
+ _s.label = 54;
3136
+ case 54:
3057
3137
  probeDocs = _k;
3058
3138
  if (probeDocs.length && nameFields.length) {
3059
3139
  diagnostics.chemicalIdDetected = detectChemicalIdFromProbe(probeDocs, nameFields);
3060
3140
  }
3061
- return [3 /*break*/, 54];
3062
- case 53:
3141
+ return [3 /*break*/, 56];
3142
+ case 55:
3063
3143
  _l = _s.sent();
3064
- return [3 /*break*/, 54];
3065
- case 54:
3066
- _s.trys.push([54, 58, , 59]);
3144
+ return [3 /*break*/, 56];
3145
+ case 56:
3146
+ _s.trys.push([56, 60, , 61]);
3067
3147
  return [4 /*yield*/, listAssistantCollections(db, dbName)];
3068
- case 55:
3148
+ case 57:
3069
3149
  allCollections = _s.sent();
3070
3150
  base = stripVersionSuffix(collection.startsWith('report-') ? collection.slice('report-'.length) : collection);
3071
3151
  alt = collection.startsWith('report-') ? base : "report-".concat(base);
3072
- if (!(alt && alt !== collection && allCollections.includes(alt))) return [3 /*break*/, 57];
3152
+ if (!(alt && alt !== collection && allCollections.includes(alt))) return [3 /*break*/, 59];
3073
3153
  return [4 /*yield*/, db.collection(alt).countDocuments({}, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
3074
- case 56:
3154
+ case 58:
3075
3155
  altCount = _s.sent();
3076
3156
  diagnostics.alternateCollection = alt;
3077
3157
  diagnostics.alternateCollectionCount = altCount;
3078
- _s.label = 57;
3079
- case 57: return [3 /*break*/, 59];
3080
- case 58:
3158
+ _s.label = 59;
3159
+ case 59: return [3 /*break*/, 61];
3160
+ case 60:
3081
3161
  _m = _s.sent();
3082
- return [3 /*break*/, 59];
3083
- case 59:
3162
+ return [3 /*break*/, 61];
3163
+ case 61:
3084
3164
  fallbackMeta.zeroDiagnostics = diagnostics;
3085
- _s.label = 60;
3086
- case 60:
3165
+ _s.label = 62;
3166
+ case 62:
3087
3167
  total = null;
3088
- if (!normalized.includeTotal) return [3 /*break*/, 62];
3168
+ if (!normalized.includeTotal) return [3 /*break*/, 64];
3089
3169
  return [4 /*yield*/, db.collection(collection).countDocuments(executedQuery, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
3090
- case 61:
3170
+ case 63:
3091
3171
  total = _s.sent();
3092
- _s.label = 62;
3093
- case 62:
3172
+ _s.label = 64;
3173
+ case 64:
3094
3174
  sanitizedDocuments = isSuperAdmin
3095
3175
  ? documents
3096
3176
  : documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
3097
3177
  requestedFields = resolveProjectionRequestedFields(findOptions.projection);
3098
- if (!(sanitizedDocuments.length && requestedFields.length)) return [3 /*break*/, 66];
3178
+ if (!(sanitizedDocuments.length && requestedFields.length)) return [3 /*break*/, 68];
3099
3179
  missingFields = requestedFields.filter(function (field) { return !hasNonEmptyValue(sanitizedDocuments, field, { treatObjectLikeAsEmpty: true }); });
3100
- if (!missingFields.length) return [3 /*break*/, 66];
3180
+ if (!missingFields.length) return [3 /*break*/, 68];
3101
3181
  _o = probeDocs;
3102
- if (_o) return [3 /*break*/, 64];
3182
+ if (_o) return [3 /*break*/, 66];
3103
3183
  return [4 /*yield*/, fetchAssistantProbeDocs({
3104
3184
  db: db,
3105
3185
  collection: collection,
@@ -3108,25 +3188,25 @@ function executeAiAssistantMongoRead(payload, context) {
3108
3188
  isSuperAdmin: isSuperAdmin,
3109
3189
  includeClientScope: shouldScopeByClient
3110
3190
  })];
3111
- case 63:
3191
+ case 65:
3112
3192
  _o = (_s.sent());
3113
- _s.label = 64;
3114
- case 64:
3193
+ _s.label = 66;
3194
+ case 66:
3115
3195
  probeDocs = _o;
3116
- if (!probeDocs.length) return [3 /*break*/, 66];
3196
+ if (!probeDocs.length) return [3 /*break*/, 68];
3117
3197
  projectionAliases = resolveFieldAliases(probeDocs, missingFields, schemaFields);
3118
- if (!Object.keys(projectionAliases).length) return [3 /*break*/, 66];
3198
+ if (!Object.keys(projectionAliases).length) return [3 /*break*/, 68];
3119
3199
  fallbackMeta.projectionAliases = {
3120
3200
  aliases: projectionAliases,
3121
3201
  attempted: true,
3122
3202
  used: false
3123
3203
  };
3124
3204
  expandedProjection = expandProjectionWithAliases(findOptions.projection, projectionAliases);
3125
- if (!(expandedProjection && expandedProjection !== findOptions.projection)) return [3 /*break*/, 66];
3205
+ if (!(expandedProjection && expandedProjection !== findOptions.projection)) return [3 /*break*/, 68];
3126
3206
  findOptions = __assign(__assign({}, findOptions), { projection: expandedProjection });
3127
3207
  normalized.findOptions.projection = expandedProjection;
3128
3208
  return [4 /*yield*/, db.collection(collection).find(executedQuery, findOptions).toArray()];
3129
- case 65:
3209
+ case 67:
3130
3210
  refreshedDocs = _s.sent();
3131
3211
  if (refreshedDocs.length) {
3132
3212
  documents = refreshedDocs;
@@ -3135,8 +3215,8 @@ function executeAiAssistantMongoRead(payload, context) {
3135
3215
  : refreshedDocs.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
3136
3216
  fallbackMeta.projectionAliases.used = true;
3137
3217
  }
3138
- _s.label = 66;
3139
- case 66:
3218
+ _s.label = 68;
3219
+ case 68:
3140
3220
  includeIds = ((_r = input.options) === null || _r === void 0 ? void 0 : _r.includeIds) === true;
3141
3221
  fieldAliases = resolveFieldAliases(sanitizedDocuments, requestedFields, schemaFields);
3142
3222
  displayDocs = Object.keys(fieldAliases).length
@@ -3151,7 +3231,7 @@ function executeAiAssistantMongoRead(payload, context) {
3151
3231
  idCustomer: customerId,
3152
3232
  isSuperAdmin: isSuperAdmin
3153
3233
  })];
3154
- case 67:
3234
+ case 69:
3155
3235
  idLookupDisplay = _s.sent();
3156
3236
  if (idLookupDisplay === null || idLookupDisplay === void 0 ? void 0 : idLookupDisplay.docs) {
3157
3237
  displayDocs = idLookupDisplay.docs;
@@ -3308,7 +3388,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
3308
3388
  }
3309
3389
  aggregateOptions = __assign(__assign({}, normalizedOptions.aggregateOptions), { readPreference: AI_ASSISTANT_READ_PREFERENCE });
3310
3390
  runAggregateWithRepair = function (pipeline, stage) { return __awaiter(_this, void 0, void 0, function () {
3311
- var docs, error_7, isDateRepair, isRankSortByRepair, repaired, docs;
3391
+ var docs, error_7, isDateRepair, isRankSortByRepair, isDottedOutputFieldRepair, repaired, docs;
3312
3392
  return __generator(this, function (_a) {
3313
3393
  switch (_a.label) {
3314
3394
  case 0:
@@ -3323,12 +3403,15 @@ function executeAiAssistantMongoAggregate(payload, context) {
3323
3403
  error_7 = _a.sent();
3324
3404
  isDateRepair = isAssistantDateArithmeticArgumentError(error_7);
3325
3405
  isRankSortByRepair = isAssistantRankSortByError(error_7);
3326
- if (!isDateRepair && !isRankSortByRepair) {
3406
+ isDottedOutputFieldRepair = isAssistantDottedOutputFieldError(error_7);
3407
+ if (!isDateRepair && !isRankSortByRepair && !isDottedOutputFieldRepair) {
3327
3408
  throw error_7;
3328
3409
  }
3329
3410
  repaired = isDateRepair
3330
3411
  ? repairAssistantDateArithmeticInPipeline(pipeline)
3331
- : repairAssistantRankSortByInPipeline(pipeline);
3412
+ : isRankSortByRepair
3413
+ ? repairAssistantRankSortByInPipeline(pipeline)
3414
+ : repairAssistantDottedOutputFieldNamesInPipeline(pipeline);
3332
3415
  if (!repaired.changed || containsForbiddenMongoOperators(repaired.pipeline)) {
3333
3416
  throw error_7;
3334
3417
  }
@@ -3353,6 +3436,14 @@ function executeAiAssistantMongoAggregate(payload, context) {
3353
3436
  reason: 'normalized_rank_sortby_single_key'
3354
3437
  };
3355
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
+ }
3356
3447
  return [2 /*return*/, { documents: docs, pipeline: repaired.pipeline }];
3357
3448
  case 4: return [2 /*return*/];
3358
3449
  }
@@ -8427,31 +8518,127 @@ function ensureAssistantMinimumDisplayColumns(display) {
8427
8518
  : rows.length;
8428
8519
  return __assign(__assign({}, display), { columns: [primary, 'Count'], rows: [(_a = {}, _a[primary] = uniqueLabels[0], _a.Count = totalCount, _a)], rowCount: 1, truncated: false });
8429
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
+ }
8430
8616
  function applyAssistantDisplayTableToResponse(value, display) {
8617
+ var _a;
8431
8618
  if (!display || !Array.isArray(display.rows)) {
8432
8619
  return value;
8433
8620
  }
8434
- var normalizedDisplay = ensureAssistantMinimumDisplayColumns(display);
8621
+ var normalizedDisplay = applyAssistantDisplayColumnHints(value, ensureAssistantMinimumDisplayColumns(display));
8435
8622
  if (!display.rows.length) {
8436
8623
  var cleaned_1 = stripAssistantMarkdownTables(value);
8437
8624
  var rowCount = typeof normalizedDisplay.rowCount === 'number' && normalizedDisplay.rowCount > 0
8438
8625
  ? normalizedDisplay.rowCount
8439
8626
  : 0;
8440
- var tableDisplay = rowCount > 0
8441
- ? {
8442
- columns: ['Metric', 'Value'],
8443
- rows: [{ Metric: 'Rows matched', Value: rowCount }],
8444
- rowCount: 1,
8445
- truncated: false,
8446
- includeIds: false
8447
- }
8448
- : {
8449
- columns: ['Result', 'Details'],
8450
- rows: [{ Result: 'No matching rows', Details: '' }],
8451
- rowCount: 0,
8452
- truncated: false,
8453
- includeIds: false
8454
- };
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
+ };
8455
8642
  var emptyTable = formatDisplayTableMarkdown(tableDisplay);
8456
8643
  if (!emptyTable) {
8457
8644
  return cleaned_1 || value;
@@ -9226,10 +9413,63 @@ function normalizeAssistantDateArithmeticArgs(expression) {
9226
9413
  }
9227
9414
  expression.$let = nextArgs;
9228
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
+ };
9229
9468
  normalizeOperatorArgs('$dateAdd');
9230
9469
  normalizeOperatorArgs('$dateSubtract');
9231
9470
  normalizeDateTruncArgs();
9232
9471
  normalizeLetArgs();
9472
+ normalizeDatePartArgs();
9233
9473
  return expression;
9234
9474
  }
9235
9475
  function normalizeAssistantNowExprPlaceholdersDeep(value) {
@@ -9262,6 +9502,13 @@ function isAssistantDateArithmeticArgumentError(error) {
9262
9502
  return message.includes('unrecognized argument to $datesubtract:')
9263
9503
  || message.includes('unrecognized argument to $dateadd:')
9264
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:')
9265
9512
  || message.includes('unrecognized parameter to $let:')
9266
9513
  || message.includes("missing 'in' parameter to $let")
9267
9514
  || message.includes("missing 'unit' parameter to $datetrunc")
@@ -9295,6 +9542,13 @@ function isAssistantRankSortByError(error) {
9295
9542
  return message.includes('$rank must be specified with a top level sortby expression with exactly one element')
9296
9543
  || message.includes('$denserank must be specified with a top level sortby expression with exactly one element');
9297
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
+ }
9298
9552
  function didAssistantValueChange(before, after) {
9299
9553
  try {
9300
9554
  return JSON.stringify(before) !== JSON.stringify(after);
@@ -9340,6 +9594,49 @@ function repairAssistantRankSortByInPipeline(pipeline) {
9340
9594
  changed: didAssistantValueChange(pipeline, repaired)
9341
9595
  };
9342
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
+ }
9343
9640
  function isMatchExpressionOperand(value) {
9344
9641
  if (typeof value === 'string') {
9345
9642
  return value.startsWith('$$');
@@ -10964,12 +11261,22 @@ function collectAssistantActiveMatchFields(query) {
10964
11261
  var fields = collectMatchFieldsByCondition(query, function (field, condition) { return isAssistantActiveFieldPath(field) && isAssistantActiveCondition(condition); });
10965
11262
  return Array.from(new Set(fields));
10966
11263
  }
10967
- function resolveReadActiveStatusFallback(query, probeDocs) {
11264
+ function resolveReadActiveStatusFallback(query, probeDocs, schemaFields) {
11265
+ var _a;
10968
11266
  var fields = collectAssistantActiveMatchFields(query);
10969
- 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)) {
10970
11275
  return null;
10971
11276
  }
10972
- 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;
10973
11280
  if (hasAnyFieldData) {
10974
11281
  return null;
10975
11282
  }
@@ -10977,6 +11284,38 @@ function resolveReadActiveStatusFallback(query, probeDocs) {
10977
11284
  if (!stripped.changed || !stripped.value || typeof stripped.value !== 'object') {
10978
11285
  return null;
10979
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
+ }
10980
11319
  return {
10981
11320
  query: stripped.value,
10982
11321
  fields: fields
@@ -12185,6 +12524,62 @@ function mergeAssistantHintValues() {
12185
12524
  });
12186
12525
  return result;
12187
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
+ ];
12188
12583
  function resolveCollectionHintsFromRoute(route, collectionNames) {
12189
12584
  var normalizedRoute = normalizeOptionalString(route);
12190
12585
  if (!normalizedRoute || !collectionNames.length) {
@@ -12233,6 +12628,15 @@ function resolveAssistantDefaultCollectionHints(message) {
12233
12628
  if (/\busers?\b/.test(text)) {
12234
12629
  push('users');
12235
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
+ }
12236
12640
  return hints;
12237
12641
  }
12238
12642
  function buildCollectionRankingDebugFromTokens(tokens, collectionNames, max) {
@@ -12495,7 +12899,7 @@ function findBestCollectionMatch(requested, collectionNames) {
12495
12899
  }
12496
12900
  function resolveAssistantCollectionName(db, dbName, requested) {
12497
12901
  return __awaiter(this, void 0, void 0, function () {
12498
- var trimmed, collectionNames, best, candidates;
12902
+ var trimmed, collectionNames, aliasCandidates, matchedAlias, best, candidates;
12499
12903
  return __generator(this, function (_a) {
12500
12904
  switch (_a.label) {
12501
12905
  case 0:
@@ -12509,6 +12913,11 @@ function resolveAssistantCollectionName(db, dbName, requested) {
12509
12913
  if (collectionNames.includes(trimmed)) {
12510
12914
  return [2 /*return*/, { name: trimmed, matched: true, candidates: [], score: 100 }];
12511
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
+ }
12512
12921
  best = findBestCollectionMatch(trimmed, collectionNames);
12513
12922
  if (best && best.score >= 20) {
12514
12923
  return [2 /*return*/, { name: best.name, matched: true, candidates: [], score: best.score }];
@@ -12526,11 +12935,150 @@ function resolveAssistantCollectionName(db, dbName, requested) {
12526
12935
  }
12527
12936
  var AI_ASSISTANT_BRIDGE_COLLECTION_ALIASES = {
12528
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',
12529
12987
  supportticket: 'support-tickets',
12530
12988
  supporttickets: 'support-tickets',
12531
12989
  ticket: 'support-tickets',
12532
12990
  tickets: 'support-tickets'
12533
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
+ };
12534
13082
  var AI_ASSISTANT_DIRECT_COLLECTION_FALLBACK_ALLOWLIST = new Set([]);
12535
13083
  var AI_ASSISTANT_SUPPORT_COLLECTION_FALLBACKS = [
12536
13084
  'support-tickets',
@@ -12597,9 +13145,8 @@ function resolveAssistantCrossCollectionFallbackCandidates(collection) {
12597
13145
  }
12598
13146
  candidates.add(candidate);
12599
13147
  };
12600
- var alias = resolveAssistantBridgeCollectionAlias(normalized)
12601
- || resolveAssistantBridgeCollectionAlias(normalizeCollectionKey(normalized));
12602
- addCandidate(alias);
13148
+ var aliasCandidates = mergeAssistantHintValues(resolveAssistantBridgeCollectionAliasCandidates(normalized), resolveAssistantBridgeCollectionAliasCandidates(normalizeCollectionKey(normalized)));
13149
+ aliasCandidates.forEach(addCandidate);
12603
13150
  if (AI_ASSISTANT_SUPPORT_COLLECTION_FALLBACKS.includes(normalized)
12604
13151
  || normalized.includes('ticket')
12605
13152
  || normalized.includes('support')) {
@@ -12916,10 +13463,7 @@ function resolveAssistantNestedPrefixCollectionCandidates(params) {
12916
13463
  }
12917
13464
  candidates.push(preferred);
12918
13465
  };
12919
- var alias = resolveAssistantBridgeCollectionAlias(normalizedPrefix);
12920
- if (alias) {
12921
- push(alias);
12922
- }
13466
+ resolveAssistantBridgeCollectionAliasCandidates(normalizedPrefix).forEach(push);
12923
13467
  push(normalizedPrefix);
12924
13468
  resolveAssistantAvailableCrossCollectionFallbacksFromNames(normalizedPrefix, params.triedCollections, params.collectionNames).forEach(push);
12925
13469
  var tokenizedPrefix = tokenizeCollectionText(normalizedPrefix);
@@ -13007,9 +13551,25 @@ function resolveAssistantNestedAggregateFallbacks(params) {
13007
13551
  });
13008
13552
  });
13009
13553
  }
13010
- function resolveAssistantBridgeCollectionAlias(value) {
13554
+ function resolveAssistantBridgeCollectionAliasCandidates(value) {
13011
13555
  var key = normalizeCollectionKey(value);
13012
- 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;
13013
13573
  }
13014
13574
  function isAssistantDirectCollectionFallbackAllowed(collection) {
13015
13575
  var normalized = normalizeOptionalString(collection);
@@ -13046,7 +13606,7 @@ function doesAssistantCollectionExistInDb(db, collection) {
13046
13606
  }
13047
13607
  function resolveAssistantReportBuilderBridgeCollection(collection_1, db_1) {
13048
13608
  return __awaiter(this, arguments, void 0, function (collection, db, dbName) {
13049
- 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;
13050
13610
  var e_35, _b, e_34, _c, e_36, _d;
13051
13611
  var _e;
13052
13612
  if (dbName === void 0) { dbName = ''; }
@@ -13057,7 +13617,8 @@ function resolveAssistantReportBuilderBridgeCollection(collection_1, db_1) {
13057
13617
  if (!normalized) {
13058
13618
  throw new Error('AI assistant report builder bridge: Collection is required.');
13059
13619
  }
13060
- alias = resolveAssistantBridgeCollectionAlias(normalized);
13620
+ aliasCandidates = resolveAssistantBridgeCollectionAliasCandidates(normalized);
13621
+ alias = aliasCandidates[0] || '';
13061
13622
  manager = (_e = resolveio_server_app_1.ResolveIOServer.getMongoManager) === null || _e === void 0 ? void 0 : _e.call(resolveio_server_app_1.ResolveIOServer);
13062
13623
  hasManager = !!(manager && typeof manager.collection === 'function');
13063
13624
  candidates = [];
@@ -13069,9 +13630,7 @@ function resolveAssistantReportBuilderBridgeCollection(collection_1, db_1) {
13069
13630
  candidates.push(value);
13070
13631
  };
13071
13632
  pushCandidate(normalized);
13072
- if (alias) {
13073
- pushCandidate(alias);
13074
- }
13633
+ aliasCandidates.forEach(pushCandidate);
13075
13634
  base = stripVersionSuffix(normalized.startsWith('report-') ? normalized.slice('report-'.length) : normalized);
13076
13635
  if (base && base !== normalized) {
13077
13636
  pushCandidate(base);
@@ -14214,6 +14773,8 @@ function buildAssistantWorkspaceRootCandidates(params) {
14214
14773
  var pathCandidates = [
14215
14774
  serverConfig['AI_ASSISTANT_WORKSPACE_ROOT'],
14216
14775
  env['AI_ASSISTANT_WORKSPACE_ROOT'],
14776
+ serverConfig['AI_ASSISTANT_ROOT_WORKSPACE'],
14777
+ env['AI_ASSISTANT_ROOT_WORKSPACE'],
14217
14778
  serverConfig['AI_TERMINAL_WORKSPACE_ROOT'],
14218
14779
  env['AI_TERMINAL_WORKSPACE_ROOT'],
14219
14780
  serverConfig['AI_DASHBOARD_WORKSPACE_ROOT'],
@@ -15764,16 +16325,16 @@ function resolveAssistantChangeModulesFromText(message) {
15764
16325
  if (/\b(invoice|invoices|invoicing|revenue|billing|payment|payments|paid)\b/i.test(text)) {
15765
16326
  push('invoice');
15766
16327
  }
15767
- if (/\b(work[\s-]*order|wo)\b/i.test(text)) {
16328
+ if (/\b(work[\s-]*order|wo)\b/i.test(text) || hasAssistantPurchaseOrderAliasTerms(text)) {
15768
16329
  push('work_order');
15769
16330
  }
15770
- if (/\b(deliver(?:y|ies)|route|dispatch|driver)\b/i.test(text)) {
16331
+ if (/\broute\b/i.test(text) || hasAssistantDeliveryAliasTerms(text)) {
15771
16332
  push('delivery');
15772
16333
  }
15773
16334
  if (/\b(blend|blending)\b/i.test(text)) {
15774
16335
  push('blend');
15775
16336
  }
15776
- if (/\b(chemical|chemicals)\b/i.test(text)) {
16337
+ if (hasAssistantChemicalCatalogAliasTerms(text)) {
15777
16338
  push('chemical');
15778
16339
  }
15779
16340
  if (/\b(job|jobs)\b/i.test(text)) {
@@ -15801,16 +16362,16 @@ function resolveAssistantChangeModulesFromPath(filePath) {
15801
16362
  if (/\binvoices?\b/.test(normalized)) {
15802
16363
  push('invoice');
15803
16364
  }
15804
- if (/\bwork[-_/ ]?order|wo[-_/ ]|orders?\b/.test(normalized)) {
16365
+ if (/\bwork[-_/ ]?order|wo[-_/ ]|orders?\b/.test(normalized) || hasAssistantPurchaseOrderAliasPathTerms(normalized)) {
15805
16366
  push('work_order');
15806
16367
  }
15807
- if (/\bdeliver|route|dispatch|driver\b/.test(normalized)) {
16368
+ if (hasAssistantDeliveryAliasPathTerms(normalized)) {
15808
16369
  push('delivery');
15809
16370
  }
15810
16371
  if (/\bblend\b/.test(normalized)) {
15811
16372
  push('blend');
15812
16373
  }
15813
- if (/\bchemical\b/.test(normalized)) {
16374
+ if (/\b(chemical|product|item)\b/.test(normalized)) {
15814
16375
  push('chemical');
15815
16376
  }
15816
16377
  if (/\bjobs?\b/.test(normalized)) {
@@ -15842,13 +16403,13 @@ function userHasAssistantChangeModuleAccess(user, module) {
15842
16403
  case 'invoice':
15843
16404
  return userHasInvoiceAccess(user);
15844
16405
  case 'work_order':
15845
- 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);
15846
16407
  case 'delivery':
15847
- 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);
15848
16409
  case 'blend':
15849
16410
  return userHasViewTokenPermission(user, /blend|chemical|mix/i);
15850
16411
  case 'chemical':
15851
- return userHasViewTokenPermission(user, /chemical|blend/i);
16412
+ return userHasViewTokenPermission(user, /chemical|blend|product|item|inventory/i);
15852
16413
  case 'job':
15853
16414
  return userHasViewTokenPermission(user, /job|work[-_/ ]?order/i);
15854
16415
  case 'portal':