@resolveio/server-lib 22.0.19 → 22.0.21

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.
@@ -498,6 +498,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
498
498
  '- For invoice data, set permissionView to an invoice-capable route (ex: /invoice/list).',
499
499
  '- Do not use /report/* routes as permissionView for data directives; use a module route that matches the collection.',
500
500
  '- For revenue/sales/billing questions, use invoices and sum paid_total (fallback to grand_total) with date_paid and Paid/Closed status when available.',
501
+ '- For blend ticket summaries, use product = blend_name (fallback chemical), total volume = chemical_recipe_quantity, and unit = lb when blend_in_pounds is true otherwise gal.',
501
502
  '- For revenue answers, always state the metric/date basis used (paid_total/date_paid vs grand_total/date_invoice). If tool verification warns about ambiguity or partial months, call that out before totals.',
502
503
  '- For time-based "last/past N" breakdowns, use full completed calendar-period windows in UTC aligned to the requested grain (day/week/month/quarter/year) by default, and present concrete start/end dates.',
503
504
  '- For relative date ranges (last/past/recent), include an upper bound <= $$NOW unless the user specifies a future end date.',
@@ -3151,7 +3152,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
3151
3152
  }
3152
3153
  function verifyAssistantAggregateReliability(params) {
3153
3154
  return __awaiter(this, void 0, void 0, function () {
3154
- var collection, collectionBase, monthKey, amountKey, baseMap, groupIndex, groupPaths, dateField, mergedMatch, dateFieldsInMatch, baseMatchNoDate, primaryDateCondition, verifyPipeline, verifyDocs, _a, verifyMap, comparedMonths, paidCloserCount, grandCloserCount, sumPaidDiffPct, sumGrandDiffPct, maxPaidDiffPct, maxGrandDiffPct, sumPaidGrandGapPct, highVarianceMonths, checks, warnings, avgPaidDiffPct, avgGrandDiffPct, avgPaidGrandGapPct, baselineMetric, rollingWindow, fullMonthWindow, rollingWindowBounds, fullMonthWindowBounds, verificationWindow, rollingStart, rollingEnd, fullMonthStart, fullMonthEndExclusive, fullMonthStart, fullMonthEndExclusive, fullMonthEndInclusiveDate, fullMonthEnd, normalizedMetric, bounds, fullMonthMatch, fullMonthDocs, fullMonthMap, fullMonthDiff, _b, alternateDateField, alternateDateCondition, bounds, bounds, alternateMatch, alternateDocs, alternateMap, alternateDiff, _c;
3155
+ var collection, collectionBase, monthKey, amountKey, baseMap, groupIndex, groupPaths, dateField, mergedMatch, dateFieldsInMatch, baseMatchNoDate, primaryDateCondition, verifyPipeline, verifyDocs, _a, verifyMap, comparedMonths, paidCloserCount, grandCloserCount, sumPaidDiffPct, sumGrandDiffPct, maxPaidDiffPct, maxGrandDiffPct, sumPaidGrandGapPct, highVarianceMonths, checks, warnings, avgPaidDiffPct, avgGrandDiffPct, avgPaidGrandGapPct, usesPaidGrandFallbackMetric, baselineMetric, rollingWindow, fullMonthWindow, rollingWindowBounds, fullMonthWindowBounds, verificationWindow, rollingStart, rollingEnd, fullMonthStart, fullMonthEndExclusive, fullMonthStart, fullMonthEndExclusive, fullMonthEndInclusiveDate, fullMonthEnd, normalizedMetric, bounds, fullMonthMatch, fullMonthDocs, fullMonthMap, fullMonthDiff, _b, alternateDateField, alternateDateCondition, bounds, bounds, alternateMatch, alternateDocs, alternateMap, alternateDiff, _c;
3155
3156
  var _d, _e;
3156
3157
  var _f;
3157
3158
  return __generator(this, function (_g) {
@@ -3252,6 +3253,7 @@ function verifyAssistantAggregateReliability(params) {
3252
3253
  avgPaidDiffPct = comparedMonths ? (sumPaidDiffPct / comparedMonths) : 0;
3253
3254
  avgGrandDiffPct = comparedMonths ? (sumGrandDiffPct / comparedMonths) : 0;
3254
3255
  avgPaidGrandGapPct = comparedMonths ? (sumPaidGrandGapPct / comparedMonths) : 0;
3256
+ usesPaidGrandFallbackMetric = hasAssistantPaidGrandFallbackExpr(params.pipeline || []);
3255
3257
  baselineMetric = 'unknown';
3256
3258
  if (comparedMonths) {
3257
3259
  if (paidCloserCount > grandCloserCount) {
@@ -3275,10 +3277,12 @@ function verifyAssistantAggregateReliability(params) {
3275
3277
  else {
3276
3278
  checks.push({
3277
3279
  name: 'Metric alignment',
3278
- status: baselineMetric === 'mixed' ? 'warn' : 'pass',
3279
- details: "Result aligns most with ".concat(baselineMetric, ".")
3280
+ status: baselineMetric === 'mixed' && !usesPaidGrandFallbackMetric ? 'warn' : 'pass',
3281
+ details: baselineMetric === 'mixed' && usesPaidGrandFallbackMetric
3282
+ ? 'Result uses explicit paid_total fallback grand_total logic.'
3283
+ : "Result aligns most with ".concat(baselineMetric, ".")
3280
3284
  });
3281
- if (baselineMetric === 'mixed') {
3285
+ if (baselineMetric === 'mixed' && !usesPaidGrandFallbackMetric) {
3282
3286
  warnings.push('Revenue appears to mix definitions across months (paid_total vs grand_total).');
3283
3287
  }
3284
3288
  checks.push({
@@ -3552,6 +3556,24 @@ function mapAssistantRevenueByMonth(documents, monthKey, valueKey) {
3552
3556
  });
3553
3557
  return mapped;
3554
3558
  }
3559
+ function hasAssistantPaidGrandFallbackExpr(value) {
3560
+ if (Array.isArray(value)) {
3561
+ return value.some(function (entry) { return hasAssistantPaidGrandFallbackExpr(entry); });
3562
+ }
3563
+ if (!value || typeof value !== 'object') {
3564
+ return false;
3565
+ }
3566
+ var ifNull = value.$ifNull;
3567
+ if (Array.isArray(ifNull) && ifNull.length >= 2) {
3568
+ var first = normalizeOptionalString(ifNull[0]).replace(/^\$/, '');
3569
+ var second = normalizeOptionalString(ifNull[1]).replace(/^\$/, '');
3570
+ var pair = new Set([first, second]);
3571
+ if (pair.has('paid_total') && pair.has('grand_total')) {
3572
+ return true;
3573
+ }
3574
+ }
3575
+ return Object.keys(value).some(function (key) { return hasAssistantPaidGrandFallbackExpr(value[key]); });
3576
+ }
3555
3577
  function mergeAssistantPreGroupMatchStages(pipeline, groupIndex) {
3556
3578
  var matches = [];
3557
3579
  for (var i = 0; i < groupIndex; i += 1) {
@@ -3957,7 +3979,7 @@ function applyAssistantVerificationNotes(value, toolResult) {
3957
3979
  return content || value || '';
3958
3980
  }
3959
3981
  var normalizedLower = String(content || '').toLowerCase();
3960
- var missing = warnings.filter(function (warning) { return !normalizedLower.includes(String(warning).toLowerCase()); });
3982
+ var missing = warnings.filter(function (warning) { return !hasAssistantEquivalentVerificationWarning(normalizedLower, warning); });
3961
3983
  if (!missing.length) {
3962
3984
  return content || value || '';
3963
3985
  }
@@ -3968,6 +3990,29 @@ function applyAssistantVerificationNotes(value, toolResult) {
3968
3990
  }
3969
3991
  return "".concat(content, "\n\n").concat(noteLines.join('\n')).trim();
3970
3992
  }
3993
+ function hasAssistantEquivalentVerificationWarning(contentLower, warning) {
3994
+ var warningLower = normalizeOptionalString(warning).toLowerCase();
3995
+ if (!warningLower) {
3996
+ return false;
3997
+ }
3998
+ if (contentLower.includes(warningLower)) {
3999
+ return true;
4000
+ }
4001
+ if (!warningLower.includes('changes monthly totals by')) {
4002
+ return false;
4003
+ }
4004
+ var pctMatch = warningLower.match(/([0-9]+(?:\.[0-9]+)?)%/);
4005
+ if (!pctMatch) {
4006
+ return false;
4007
+ }
4008
+ if (!/date[_\s-]?paid/.test(warningLower) || !/date[_\s-]?invoice/.test(warningLower)) {
4009
+ return false;
4010
+ }
4011
+ return contentLower.includes('changes monthly totals by')
4012
+ && contentLower.includes("".concat(pctMatch[1], "%"))
4013
+ && /date[_\s-]?paid/.test(contentLower)
4014
+ && /date[_\s-]?invoice/.test(contentLower);
4015
+ }
3971
4016
  function applyAssistantDatedReportWindow(value, toolResult) {
3972
4017
  var content = normalizeOptionalString(value);
3973
4018
  var window = resolveAssistantDatedReportWindow(toolResult);
@@ -5805,12 +5850,31 @@ function resolveAssistantNumericValue(value) {
5805
5850
  return value;
5806
5851
  }
5807
5852
  if (typeof value === 'string') {
5808
- var cleaned = value.replace(/[^0-9.+-]/g, '');
5809
- if (!cleaned) {
5853
+ var trimmed = value.trim();
5854
+ if (!trimmed) {
5855
+ return null;
5856
+ }
5857
+ var negative = false;
5858
+ var candidate = trimmed;
5859
+ var accountingMatch = candidate.match(/^\((.+)\)$/);
5860
+ if (accountingMatch === null || accountingMatch === void 0 ? void 0 : accountingMatch[1]) {
5861
+ negative = true;
5862
+ candidate = accountingMatch[1].trim();
5863
+ }
5864
+ candidate = candidate.replace(/^\$/, '').replace(/,/g, '');
5865
+ if (!candidate || !/^[+-]?(?:\d+|\d*\.\d+)%?$/.test(candidate) || !/[0-9]/.test(candidate)) {
5866
+ return null;
5867
+ }
5868
+ var normalized = candidate.endsWith('%') ? candidate.slice(0, -1) : candidate;
5869
+ var parsed = Number(normalized);
5870
+ if (!Number.isFinite(parsed)) {
5871
+ return null;
5872
+ }
5873
+ var signed = negative ? -parsed : parsed;
5874
+ if (!Number.isFinite(signed)) {
5810
5875
  return null;
5811
5876
  }
5812
- var parsed = Number(cleaned);
5813
- return Number.isFinite(parsed) ? parsed : null;
5877
+ return signed;
5814
5878
  }
5815
5879
  return null;
5816
5880
  }