@resolveio/server-lib 22.1.10 → 22.1.12

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.
@@ -46,6 +46,7 @@ export type AiAssistantMongoAggregateInput = {
46
46
  access?: string;
47
47
  readonly?: boolean;
48
48
  };
49
+ __assistantMessage?: string;
49
50
  __assistantRetryState?: AiAssistantCollectionRetryState;
50
51
  };
51
52
  type AiAssistantDisplayTable = {
@@ -112,9 +113,13 @@ export declare function buildDisplayTable(docs: any[], options?: {
112
113
  export declare function formatDisplayTableMarkdown(display: AiAssistantDisplayTable): string;
113
114
  export declare function resolveAssistantReadDisplayMaxRows(limit: number | undefined, rowCount: number): number;
114
115
  export declare function normalizeAssistantNowExprPlaceholders(value: any): any;
116
+ export declare function repairAssistantFieldPathReferenceInPipeline(pipeline: Array<Record<string, any>>, fieldPath: string): {
117
+ pipeline: Array<Record<string, any>>;
118
+ changed: boolean;
119
+ };
115
120
  export declare function rewriteMatchExpressionsToExpr(match: any): any;
116
121
  export declare function normalizeAssistantMonthlyCalendarWindowPipeline(pipeline: Array<Record<string, any>>): Array<Record<string, any>>;
117
- export declare function normalizeAssistantAggregatePipeline(pipeline?: Array<Record<string, any>>, collection?: string): Array<Record<string, any>>;
122
+ export declare function normalizeAssistantAggregatePipeline(pipeline?: Array<Record<string, any>>, collection?: string, originalMessage?: string): Array<Record<string, any>>;
118
123
  export declare function stripQueryFieldPathsDeep(query: any, fieldsToStrip: string[]): any;
119
124
  export declare function stripScopedFieldsFromPipeline(pipeline: any[], fieldsToStrip: string[]): any[];
120
125
  export declare function rewriteEmbeddedMatchObjects(query: any): any;
@@ -119,6 +119,7 @@ exports.buildDisplayTable = buildDisplayTable;
119
119
  exports.formatDisplayTableMarkdown = formatDisplayTableMarkdown;
120
120
  exports.resolveAssistantReadDisplayMaxRows = resolveAssistantReadDisplayMaxRows;
121
121
  exports.normalizeAssistantNowExprPlaceholders = normalizeAssistantNowExprPlaceholders;
122
+ exports.repairAssistantFieldPathReferenceInPipeline = repairAssistantFieldPathReferenceInPipeline;
122
123
  exports.rewriteMatchExpressionsToExpr = rewriteMatchExpressionsToExpr;
123
124
  exports.normalizeAssistantMonthlyCalendarWindowPipeline = normalizeAssistantMonthlyCalendarWindowPipeline;
124
125
  exports.normalizeAssistantAggregatePipeline = normalizeAssistantAggregatePipeline;
@@ -3367,7 +3368,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
3367
3368
  ? applyClientScopeFilter(baseQuery, normalizedClient, isSuperAdmin)
3368
3369
  : baseQuery;
3369
3370
  scopedQuery = applyCustomerScopeFilter(clientScopedQuery, collection, customerId, isSuperAdmin);
3370
- normalizedPipeline = normalizeAssistantAggregatePipeline(input.pipeline, collection);
3371
+ normalizedPipeline = normalizeAssistantAggregatePipeline(input.pipeline, collection, input.__assistantMessage);
3371
3372
  sanitizedPipeline = normalizedPipeline;
3372
3373
  if (!isSuperAdmin && customerId) {
3373
3374
  strippedPipeline = stripScopedFieldsFromPipelineWithMeta(normalizedPipeline, ['id_customer', 'other.id_customer']);
@@ -3388,7 +3389,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
3388
3389
  }
3389
3390
  aggregateOptions = __assign(__assign({}, normalizedOptions.aggregateOptions), { readPreference: AI_ASSISTANT_READ_PREFERENCE });
3390
3391
  runAggregateWithRepair = function (pipeline, stage) { return __awaiter(_this, void 0, void 0, function () {
3391
- var docs, error_7, isDateRepair, isRankSortByRepair, isDottedOutputFieldRepair, repaired, docs;
3392
+ var docs, error_7, isDateRepair, isRankSortByRepair, isDottedOutputFieldRepair, repaired, dottedFieldPath, dottedFieldReferenceRepairUsed, pathReferenceRepair, docs;
3392
3393
  return __generator(this, function (_a) {
3393
3394
  switch (_a.label) {
3394
3395
  case 0:
@@ -3412,6 +3413,21 @@ function executeAiAssistantMongoAggregate(payload, context) {
3412
3413
  : isRankSortByRepair
3413
3414
  ? repairAssistantRankSortByInPipeline(pipeline)
3414
3415
  : repairAssistantDottedOutputFieldNamesInPipeline(pipeline);
3416
+ dottedFieldPath = null;
3417
+ dottedFieldReferenceRepairUsed = false;
3418
+ if (isDottedOutputFieldRepair) {
3419
+ dottedFieldPath = extractAssistantDottedFieldPathFromError(error_7);
3420
+ if (dottedFieldPath) {
3421
+ pathReferenceRepair = repairAssistantFieldPathReferenceInPipeline(repaired.pipeline, dottedFieldPath);
3422
+ if (pathReferenceRepair.changed) {
3423
+ dottedFieldReferenceRepairUsed = true;
3424
+ repaired = {
3425
+ pipeline: pathReferenceRepair.pipeline,
3426
+ changed: repaired.changed || pathReferenceRepair.changed
3427
+ };
3428
+ }
3429
+ }
3430
+ }
3415
3431
  if (!repaired.changed || containsForbiddenMongoOperators(repaired.pipeline)) {
3416
3432
  throw error_7;
3417
3433
  }
@@ -3441,7 +3457,10 @@ function executeAiAssistantMongoAggregate(payload, context) {
3441
3457
  attempted: true,
3442
3458
  used: true,
3443
3459
  stage: stage,
3444
- reason: 'normalized_dotted_output_field_names'
3460
+ reason: dottedFieldReferenceRepairUsed
3461
+ ? 'normalized_dotted_output_field_names_and_field_path_references'
3462
+ : 'normalized_dotted_output_field_names',
3463
+ fieldPath: dottedFieldPath || undefined
3445
3464
  };
3446
3465
  }
3447
3466
  return [2 /*return*/, { documents: docs, pipeline: repaired.pipeline }];
@@ -4798,6 +4817,12 @@ function buildAssistantToolRequest(directive, payload) {
4798
4817
  if (!request.mongo && (payload === null || payload === void 0 ? void 0 : payload.mongo)) {
4799
4818
  request.mongo = payload.mongo;
4800
4819
  }
4820
+ if (directive.type === 'aggregate' && !request.__assistantMessage) {
4821
+ var message = normalizeOptionalString(payload === null || payload === void 0 ? void 0 : payload.message);
4822
+ if (message) {
4823
+ request.__assistantMessage = message;
4824
+ }
4825
+ }
4801
4826
  return request;
4802
4827
  }
4803
4828
  function buildAssistantTrimmedStringExpr(value) {
@@ -9549,6 +9574,23 @@ function isAssistantDottedOutputFieldError(error) {
9549
9574
  }
9550
9575
  return message.includes("fieldpath field names may not contain '.'");
9551
9576
  }
9577
+ function extractAssistantDottedFieldPathFromError(error) {
9578
+ var message = normalizeOptionalString(error === null || error === void 0 ? void 0 : error.message);
9579
+ if (!message) {
9580
+ return null;
9581
+ }
9582
+ var quotedMatch = message.match(/given\s+'([^']+)'/i);
9583
+ if (quotedMatch && quotedMatch[1]) {
9584
+ var normalized = normalizeOptionalString(quotedMatch[1]);
9585
+ return normalized.includes('.') ? normalized : null;
9586
+ }
9587
+ var plainMatch = message.match(/given\s+([a-z0-9_.-]+)/i);
9588
+ if (plainMatch && plainMatch[1]) {
9589
+ var normalized = normalizeOptionalString(plainMatch[1]);
9590
+ return normalized.includes('.') ? normalized : null;
9591
+ }
9592
+ return null;
9593
+ }
9552
9594
  function didAssistantValueChange(before, after) {
9553
9595
  try {
9554
9596
  return JSON.stringify(before) !== JSON.stringify(after);
@@ -9637,6 +9679,59 @@ function repairAssistantDottedOutputFieldNamesInPipeline(pipeline) {
9637
9679
  changed: didAssistantValueChange(pipeline, repaired)
9638
9680
  };
9639
9681
  }
9682
+ function buildAssistantGetFieldExpressionFromPath(path) {
9683
+ var normalizedPath = normalizeOptionalString(path);
9684
+ var segments = normalizedPath.split('.').filter(Boolean);
9685
+ if (!segments.length) {
9686
+ return "$".concat(normalizedPath);
9687
+ }
9688
+ var expression = "$".concat(segments[0]);
9689
+ for (var i = 1; i < segments.length; i += 1) {
9690
+ expression = {
9691
+ $getField: {
9692
+ field: segments[i],
9693
+ input: expression
9694
+ }
9695
+ };
9696
+ }
9697
+ return expression;
9698
+ }
9699
+ function repairAssistantFieldPathReferenceInPipeline(pipeline, fieldPath) {
9700
+ var normalizedFieldPath = normalizeOptionalString(fieldPath).replace(/^\$+/, '');
9701
+ if (!normalizedFieldPath || !normalizedFieldPath.includes('.')) {
9702
+ return { pipeline: pipeline, changed: false };
9703
+ }
9704
+ var targetRef = "$".concat(normalizedFieldPath);
9705
+ var rewriteValue = function (value) {
9706
+ if (Array.isArray(value)) {
9707
+ return value.map(function (entry) { return rewriteValue(entry); });
9708
+ }
9709
+ if (typeof value === 'string') {
9710
+ if (value === targetRef) {
9711
+ return buildAssistantGetFieldExpressionFromPath(normalizedFieldPath);
9712
+ }
9713
+ if (value.startsWith("".concat(targetRef, "."))) {
9714
+ return buildAssistantGetFieldExpressionFromPath(value.slice(1));
9715
+ }
9716
+ return value;
9717
+ }
9718
+ if (!value || typeof value !== 'object' || value instanceof Date || value instanceof RegExp || isMongoObjectId(value)) {
9719
+ return value;
9720
+ }
9721
+ var next = {};
9722
+ Object.keys(value).forEach(function (key) {
9723
+ next[key] = rewriteValue(value[key]);
9724
+ });
9725
+ return next;
9726
+ };
9727
+ var repaired = Array.isArray(pipeline)
9728
+ ? pipeline.map(function (stage) { return rewriteValue(stage); })
9729
+ : pipeline;
9730
+ return {
9731
+ pipeline: repaired,
9732
+ changed: didAssistantValueChange(pipeline, repaired)
9733
+ };
9734
+ }
9640
9735
  function isMatchExpressionOperand(value) {
9641
9736
  if (typeof value === 'string') {
9642
9737
  return value.startsWith('$$');
@@ -10178,7 +10273,75 @@ function normalizeAssistantSortTieBreakersForLimit(pipeline) {
10178
10273
  return __assign(__assign({}, stage), { $sort: __assign(__assign({}, sort), { _id: 1 }) });
10179
10274
  });
10180
10275
  }
10181
- function normalizeAssistantAggregatePipeline(pipeline, collection) {
10276
+ function resolveAssistantRecentGroupedRecordLimit(message) {
10277
+ var normalized = normalizeOptionalString(message);
10278
+ if (!normalized) {
10279
+ return null;
10280
+ }
10281
+ if (!/\b(last|latest|recent)\b/i.test(normalized)) {
10282
+ return null;
10283
+ }
10284
+ var groupedHint = /\bgroup(?:ed|ing)?\s+by\b/i.test(normalized)
10285
+ || /\bby\s+(status|state|type)\b/i.test(normalized);
10286
+ if (!groupedHint) {
10287
+ return null;
10288
+ }
10289
+ if (/\b(by|per)\s+(day|week|month|quarter|year)\b/i.test(normalized) || /\btrend|over\s+time|timeline\b/i.test(normalized)) {
10290
+ return null;
10291
+ }
10292
+ var tokenMatch = normalized.match(/\b(?:last|latest|recent)\s+(\d{1,4})\s+([a-z][a-z_-]*)\b/i);
10293
+ if (!tokenMatch) {
10294
+ return null;
10295
+ }
10296
+ var entityToken = normalizeOptionalString(tokenMatch[2]).toLowerCase();
10297
+ if (['minute', 'minutes', 'hour', 'hours', 'day', 'days', 'week', 'weeks', 'month', 'months', 'quarter', 'quarters', 'year', 'years'].includes(entityToken)) {
10298
+ return null;
10299
+ }
10300
+ var value = Number(tokenMatch[1]);
10301
+ if (!Number.isFinite(value) || value <= 0) {
10302
+ return null;
10303
+ }
10304
+ return Math.max(1, Math.min((0, common_1.round)(value), AI_ASSISTANT_MONGO_MAX_LIMIT));
10305
+ }
10306
+ function normalizeAssistantRecentGroupedLimitBeforeGroup(pipeline, message) {
10307
+ var _a;
10308
+ var requestedLimit = resolveAssistantRecentGroupedRecordLimit(message || '');
10309
+ if (!requestedLimit || !Array.isArray(pipeline) || !pipeline.length) {
10310
+ return pipeline;
10311
+ }
10312
+ var groupIndex = findAggregateGroupIndex(pipeline);
10313
+ if (groupIndex <= 0) {
10314
+ return pipeline;
10315
+ }
10316
+ var hasPreGroupLimit = pipeline
10317
+ .slice(0, groupIndex)
10318
+ .some(function (stage) { return stage && typeof stage === 'object' && typeof stage.$limit === 'number' && stage.$limit > 0; });
10319
+ if (hasPreGroupLimit) {
10320
+ return pipeline;
10321
+ }
10322
+ var postGroupLimitIndex = pipeline.findIndex(function (stage, index) {
10323
+ return index > groupIndex
10324
+ && stage
10325
+ && typeof stage === 'object'
10326
+ && typeof stage.$limit === 'number'
10327
+ && stage.$limit > 0;
10328
+ });
10329
+ var nextPipeline = pipeline
10330
+ .map(function (stage) { return (stage && typeof stage === 'object' && !Array.isArray(stage) ? __assign({}, stage) : stage); })
10331
+ .filter(function (_stage, index) { return index !== postGroupLimitIndex; });
10332
+ var insertionIndex = groupIndex;
10333
+ var hasPreGroupSort = nextPipeline
10334
+ .slice(0, groupIndex)
10335
+ .some(function (stage) { return stage && typeof stage === 'object' && stage.$sort && typeof stage.$sort === 'object'; });
10336
+ if (!hasPreGroupSort) {
10337
+ var dateField = findAggregateDateField(nextPipeline) || 'createdAt';
10338
+ nextPipeline.splice(insertionIndex, 0, { $sort: (_a = {}, _a[dateField] = -1, _a._id = -1, _a) });
10339
+ insertionIndex += 1;
10340
+ }
10341
+ nextPipeline.splice(insertionIndex, 0, { $limit: requestedLimit });
10342
+ return nextPipeline;
10343
+ }
10344
+ function normalizeAssistantAggregatePipeline(pipeline, collection, originalMessage) {
10182
10345
  if (!Array.isArray(pipeline)) {
10183
10346
  return [];
10184
10347
  }
@@ -10205,7 +10368,8 @@ function normalizeAssistantAggregatePipeline(pipeline, collection) {
10205
10368
  return normalizeAssistantNowExprPlaceholdersDeep(next);
10206
10369
  });
10207
10370
  var stableSortPipeline = normalizeAssistantSortTieBreakersForLimit(normalizedPipeline);
10208
- return normalizeAssistantMonthlyCalendarWindowPipeline(stableSortPipeline);
10371
+ var recordLimitedPipeline = normalizeAssistantRecentGroupedLimitBeforeGroup(stableSortPipeline, originalMessage);
10372
+ return normalizeAssistantMonthlyCalendarWindowPipeline(recordLimitedPipeline);
10209
10373
  }
10210
10374
  function buildAssistantAggregatePipeline(query, pipeline) {
10211
10375
  var _a;
@@ -12837,8 +13001,27 @@ function isAssistantCollectionRefinementOf(currentCollection, genericCollection)
12837
13001
  || current.endsWith("_".concat(generic))
12838
13002
  || current.includes("_".concat(generic, "_"));
12839
13003
  }
13004
+ function resolveAssistantCollectionScore(collectionRanking, collectionName) {
13005
+ var _a;
13006
+ var ranked = Array.isArray(collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked) ? collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked : [];
13007
+ var rankedScore = (_a = ranked.find(function (entry) { return (entry === null || entry === void 0 ? void 0 : entry.name) === collectionName; })) === null || _a === void 0 ? void 0 : _a.score;
13008
+ if (typeof rankedScore === 'number') {
13009
+ return rankedScore;
13010
+ }
13011
+ var tokens = Array.isArray(collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.tokens)
13012
+ ? collectionRanking.tokens.filter(function (token) { return typeof token === 'string' && !!token; })
13013
+ : [];
13014
+ if (!tokens.length) {
13015
+ return 0;
13016
+ }
13017
+ var rankingWeights = collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.tokenWeights;
13018
+ var hasRankingWeights = rankingWeights && typeof rankingWeights === 'object';
13019
+ var weights = hasRankingWeights
13020
+ ? rankingWeights
13021
+ : computeCollectionTokenWeights(tokens).weights;
13022
+ return scoreCollectionMatch(tokens, collectionName, weights);
13023
+ }
12840
13024
  function resolveAssistantCollectionOverride(collectionRanking, currentCollection) {
12841
- var _a, _b;
12842
13025
  var ranked = Array.isArray(collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked) ? collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked : [];
12843
13026
  if (!ranked.length) {
12844
13027
  return null;
@@ -12860,7 +13043,7 @@ function resolveAssistantCollectionOverride(collectionRanking, currentCollection
12860
13043
  if (current === top.name) {
12861
13044
  return null;
12862
13045
  }
12863
- var currentScore = (_b = (_a = ranked.find(function (entry) { return entry.name === current; })) === null || _a === void 0 ? void 0 : _a.score) !== null && _b !== void 0 ? _b : 0;
13046
+ var currentScore = resolveAssistantCollectionScore(collectionRanking, current);
12864
13047
  if (currentScore >= AI_ASSISTANT_COLLECTION_OVERRIDE_MIN_SCORE
12865
13048
  && isAssistantGenericCollectionName(top.name)
12866
13049
  && isAssistantCollectionRefinementOf(current, top.name)) {
@@ -12869,7 +13052,7 @@ function resolveAssistantCollectionOverride(collectionRanking, currentCollection
12869
13052
  var scoreGap = top.score - currentScore;
12870
13053
  var currentIsVersion = isVersionCollectionName(current);
12871
13054
  var topIsVersion = isVersionCollectionName(top.name);
12872
- if (scoreGap < AI_ASSISTANT_COLLECTION_OVERRIDE_SCORE_GAP && !(currentIsVersion && !topIsVersion)) {
13055
+ if (scoreGap <= AI_ASSISTANT_COLLECTION_OVERRIDE_SCORE_GAP && !(currentIsVersion && !topIsVersion)) {
12873
13056
  return null;
12874
13057
  }
12875
13058
  var reason = currentIsVersion && !topIsVersion