@resolveio/server-lib 22.0.13 → 22.0.15

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.
@@ -373,7 +373,7 @@ var AI_ASSISTANT_TERM_SYNONYMS = [
373
373
  var AI_ASSISTANT_REPORT_BUILDER_EXPERT_PLAYBOOK = [
374
374
  'Report Builder Bridge Expert Playbook (execute in order for every data request):',
375
375
  '1) Determine if data is required.',
376
- '- If user asks for counts, lists, totals, trends, rankings, or "recent/last", run a report builder directive before answering.',
376
+ '- If user asks for counts, lists, totals, trends, rankings, or "recent/last", run a data directive before answering.',
377
377
  '',
378
378
  'Report style mapping (always apply):',
379
379
  '- Dated report: any breakdown over time (per day/week/month/quarter/year, trends, time-series comparisons).',
@@ -388,7 +388,7 @@ var AI_ASSISTANT_REPORT_BUILDER_EXPERT_PLAYBOOK = [
388
388
  '',
389
389
  '3) Enforce permissions and scope in the directive.',
390
390
  '- Always include permissionView.',
391
- '- Use /report-builder as the default permissionView for data directives; avoid /report/* routes.',
391
+ '- Prefer module-specific permissionView routes (for example /invoice/list for invoices). Avoid /report/* routes and only use /report-builder when the user is explicitly asking about report building.',
392
392
  '- Assume non-super-admin unless explicitly told otherwise.',
393
393
  '- Invoice-like collections require invoice view access.',
394
394
  '- Customer portal users must stay in their own customer scope.',
@@ -492,8 +492,8 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
492
492
  '- REPORT_BUILDER_READ: {"collection":"<name>","query":{...},"options":{"projection":{...},"sort":{...},"limit":20},"permissionView":"</route>"}',
493
493
  '- If you need grouped/aggregated data (totals by user, rankings, trends), end your response with a single line exactly in this format:',
494
494
  '- REPORT_BUILDER_AGG: {"collection":"<name>","pipeline":[...],"options":{"allowDiskUse":true,"limit":20},"permissionView":"</route>"}',
495
- '- For invoice data, set permissionView to an invoice-capable route (ex: /invoice/list or /report-builder/list).',
496
- '- Do not use /report/* routes as permissionView for data directives; use /report-builder or a module route.',
495
+ '- For invoice data, set permissionView to an invoice-capable route (ex: /invoice/list).',
496
+ '- Do not use /report/* routes as permissionView for data directives; use a module route that matches the collection.',
497
497
  '- For revenue/sales/billing questions, use invoices and sum paid_total (fallback to grand_total) with date_paid and Paid/Closed status when available.',
498
498
  '- 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.',
499
499
  '- For relative date ranges (last/past/recent), include an upper bound <= $$NOW unless the user specifies a future end date.',
@@ -1591,7 +1591,10 @@ function executeAiAssistantCodexRun(payload, context) {
1591
1591
  workingDirectory: workspaceRoot,
1592
1592
  sandboxMode: 'read-only',
1593
1593
  skipGitRepoCheck: true,
1594
- modelReasoningEffort: resolveCodexThoughtLevel(),
1594
+ modelReasoningEffort: resolveCodexThoughtLevel({
1595
+ message: message,
1596
+ attachmentText: attachmentData.promptText
1597
+ }),
1595
1598
  networkAccessEnabled: false,
1596
1599
  webSearchMode: 'disabled',
1597
1600
  webSearchEnabled: false,
@@ -3624,7 +3627,7 @@ function buildAssistantToolRequest(directive, payload) {
3624
3627
  var base = directive.payload && typeof directive.payload === 'object' ? directive.payload : {};
3625
3628
  var request = __assign({}, base);
3626
3629
  if (!request.permissionView) {
3627
- request.permissionView = '/report-builder';
3630
+ request.permissionView = resolveDefaultAssistantPermissionView(request.collection);
3628
3631
  }
3629
3632
  request.permissionView = normalizeAssistantPermissionView(request.permissionView, request.collection);
3630
3633
  if (!request.id_client) {
@@ -3638,21 +3641,53 @@ function buildAssistantToolRequest(directive, payload) {
3638
3641
  }
3639
3642
  return request;
3640
3643
  }
3644
+ function resolveDefaultAssistantPermissionView(collection) {
3645
+ var normalizedCollection = normalizeOptionalString(collection).toLowerCase();
3646
+ if (!normalizedCollection) {
3647
+ return '/report-builder';
3648
+ }
3649
+ var base = stripVersionSuffix(normalizedCollection.startsWith('report-')
3650
+ ? normalizedCollection.slice('report-'.length)
3651
+ : normalizedCollection);
3652
+ if (!base) {
3653
+ return '/report-builder';
3654
+ }
3655
+ if (requiresInvoicePermission(base)) {
3656
+ return '/invoice/list';
3657
+ }
3658
+ if (base.startsWith('sales-tax')) {
3659
+ return '/sales-tax/list';
3660
+ }
3661
+ if (base.startsWith('expense')) {
3662
+ return '/expense/list';
3663
+ }
3664
+ if (base.startsWith('distribution')) {
3665
+ return '/distribution/list';
3666
+ }
3667
+ if (base.startsWith('prospective-client')) {
3668
+ return '/prospective-client/list';
3669
+ }
3670
+ if (base.startsWith('client')) {
3671
+ return '/client/list';
3672
+ }
3673
+ if (base.startsWith('employee')) {
3674
+ return '/employee/list';
3675
+ }
3676
+ return '/report-builder';
3677
+ }
3641
3678
  function normalizeAssistantPermissionView(permissionView, collection) {
3642
3679
  var normalizedPermission = normalizeOptionalString(permissionView);
3643
3680
  var normalizedCollection = normalizeOptionalString(collection);
3644
3681
  var loweredPermission = normalizedPermission.toLowerCase();
3682
+ var fallbackPermission = resolveDefaultAssistantPermissionView(normalizedCollection);
3645
3683
  if (!normalizedPermission) {
3646
- return '/report-builder';
3684
+ return fallbackPermission;
3647
3685
  }
3648
3686
  if (loweredPermission === '/report-builder' || loweredPermission.startsWith('/report-builder/')) {
3649
- return '/report-builder';
3687
+ return fallbackPermission;
3650
3688
  }
3651
3689
  if (loweredPermission === '/report' || loweredPermission.startsWith('/report/')) {
3652
- if (requiresInvoicePermission(normalizedCollection)) {
3653
- return '/invoice/list';
3654
- }
3655
- return '/report-builder';
3690
+ return fallbackPermission;
3656
3691
  }
3657
3692
  return normalizedPermission;
3658
3693
  }
@@ -4033,14 +4068,13 @@ function buildAssistantToolErrorMessage(error, directive, request) {
4033
4068
  var _a, _b;
4034
4069
  var rawMessage = normalizeOptionalString(error === null || error === void 0 ? void 0 : error.message) || 'Unable to access data.';
4035
4070
  var normalized = rawMessage.toLowerCase();
4036
- var routeHint = normalizeOptionalString(request === null || request === void 0 ? void 0 : request.permissionView)
4037
- || normalizeOptionalString((_a = directive.payload) === null || _a === void 0 ? void 0 : _a.permissionView);
4038
- var collection = normalizeOptionalString(request === null || request === void 0 ? void 0 : request.collection) || normalizeOptionalString((_b = directive.payload) === null || _b === void 0 ? void 0 : _b.collection);
4071
+ var collection = normalizeOptionalString(request === null || request === void 0 ? void 0 : request.collection) || normalizeOptionalString((_a = directive.payload) === null || _a === void 0 ? void 0 : _a.collection);
4072
+ var routeHint = resolveAssistantErrorRouteHint(normalizeOptionalString(request === null || request === void 0 ? void 0 : request.permissionView) || normalizeOptionalString((_b = directive.payload) === null || _b === void 0 ? void 0 : _b.permissionView), collection);
4039
4073
  var routeLine = routeHint
4040
4074
  ? "Open ".concat(routeHint, " in the app to view this data or request access.")
4041
- : 'Open the related screen in the app to view this data or request access.';
4075
+ : 'Request access to the related module in the app.';
4042
4076
  if (!routeHint && collection && requiresInvoicePermission(collection)) {
4043
- routeLine = 'Open /invoice/list or /report-builder/list to view this data or request access.';
4077
+ routeLine = 'Open /invoice/list in the app to view this data or request access.';
4044
4078
  }
4045
4079
  if (normalized.includes('permission scope required')) {
4046
4080
  return "I need a permission scope to access that data. ".concat(routeLine);
@@ -4057,14 +4091,30 @@ function buildAssistantToolErrorMessage(error, directive, request) {
4057
4091
  if (normalized.includes('undefined variable') && normalized.includes('now_minus')) {
4058
4092
  return "The query used an unsupported relative date token. Please retry; the assistant now normalizes relative dates automatically. ".concat(routeLine);
4059
4093
  }
4094
+ if (normalized.includes('invalid character for a variable name') && (normalized.includes('now-') || normalized.includes('now+'))) {
4095
+ return "The query used an unsupported relative date token. Please retry; the assistant now normalizes relative dates automatically. ".concat(routeLine);
4096
+ }
4060
4097
  if (normalized.includes('report builder bridge') && normalized.includes('not configured')) {
4061
- return "That dataset is not configured for report builder access yet. ".concat(routeLine);
4098
+ return "That dataset is not configured for assistant data access yet. ".concat(routeLine);
4062
4099
  }
4063
4100
  if (normalized.includes('collection is required')) {
4064
4101
  return 'I need a valid collection to read from. Please specify which screen or dataset you want.';
4065
4102
  }
4066
4103
  return "I couldn't access the requested data. ".concat(routeLine);
4067
4104
  }
4105
+ function resolveAssistantErrorRouteHint(routeHint, collection) {
4106
+ var normalizedHint = normalizeOptionalString(routeHint);
4107
+ if (!normalizedHint) {
4108
+ var fallback = resolveDefaultAssistantPermissionView(collection);
4109
+ return fallback.startsWith('/report-builder') ? '' : fallback;
4110
+ }
4111
+ var loweredHint = normalizedHint.toLowerCase();
4112
+ if (loweredHint.startsWith('/report-builder') || loweredHint === '/report' || loweredHint.startsWith('/report/')) {
4113
+ var fallback = resolveDefaultAssistantPermissionView(collection);
4114
+ return fallback.startsWith('/report-builder') ? '' : fallback;
4115
+ }
4116
+ return normalizedHint;
4117
+ }
4068
4118
  function deriveAssistantStreamStatus(event) {
4069
4119
  var _a;
4070
4120
  if (!event || !event.type) {
@@ -5599,8 +5649,25 @@ function resolveAssistantNumericValue(value) {
5599
5649
  function isAssistantPercentColumn(column) {
5600
5650
  return /(percent|pct|percentage|ratio|rate)\b/.test(column);
5601
5651
  }
5652
+ var ASSISTANT_NON_CURRENCY_COLUMN_PATTERN = /\b(invoice\s*number|count|qty|quantity|index|rank|sequence|seq|id|code|ticket|number)\b/;
5653
+ var ASSISTANT_CURRENCY_HINT_PATTERN = /\b(amount|price|cost|balance|fee|revenue|tax|billing|charge|payment|profit|margin|due)\b/;
5654
+ var ASSISTANT_MONEY_TOTAL_PATTERN = /\b(sub\s*total|subtotal|grand\s*total|paid\s*total)\b/;
5655
+ var ASSISTANT_TOTAL_WITH_MONEY_HINT_PATTERN = /\btotal\b.*\b(amount|revenue|sales|tax|price|cost|balance|paid|due|charge|billing|profit|margin)\b/;
5602
5656
  function isAssistantCurrencyColumn(column) {
5603
- return /(amount|total|price|cost|balance|fee|revenue|invoice|usd|tax|subtotal|paid|billing|sales)\b/.test(column);
5657
+ var normalized = String(column || '').toLowerCase().replace(/[_-]+/g, ' ').trim();
5658
+ if (!normalized) {
5659
+ return false;
5660
+ }
5661
+ var hasMoneyHint = ASSISTANT_CURRENCY_HINT_PATTERN.test(normalized)
5662
+ || ASSISTANT_MONEY_TOTAL_PATTERN.test(normalized)
5663
+ || ASSISTANT_TOTAL_WITH_MONEY_HINT_PATTERN.test(normalized);
5664
+ if (ASSISTANT_NON_CURRENCY_COLUMN_PATTERN.test(normalized) && !hasMoneyHint) {
5665
+ return false;
5666
+ }
5667
+ if (/\btotal\b/.test(normalized) && !hasMoneyHint) {
5668
+ return false;
5669
+ }
5670
+ return hasMoneyHint;
5604
5671
  }
5605
5672
  function isAssistantDateColumn(column) {
5606
5673
  return /(date|time|created|updated|timestamp|at)\b/.test(column);
@@ -5914,6 +5981,7 @@ function sanitizeAssistantProjection(projection) {
5914
5981
  }
5915
5982
  var AGG_MATCH_EXPR_OPERATORS = new Set(['$eq', '$ne', '$gt', '$gte', '$lt', '$lte']);
5916
5983
  var ASSISTANT_NOW_RELATIVE_PATTERN = /^\$\$NOW_(MINUS|PLUS)_([0-9]+)_(MINUTES?|HOURS?|DAYS?|WEEKS?|MONTHS?|YEARS?)$/i;
5984
+ var ASSISTANT_NOW_RELATIVE_COMPACT_PATTERN = /^\$\$NOW([+-])([0-9]+)\s*(MINUTES?|MINS?|MIN|HOURS?|HRS?|HR|DAYS?|WEEKS?|WKS?|WK|MONTHS?|MOS?|MO|M|YEARS?|YRS?|YR|Y)$/i;
5917
5985
  function normalizeAssistantTimeUnit(raw) {
5918
5986
  var normalized = String(raw || '').toLowerCase();
5919
5987
  if (normalized.startsWith('minute')) {
@@ -5933,21 +6001,54 @@ function normalizeAssistantTimeUnit(raw) {
5933
6001
  }
5934
6002
  return 'year';
5935
6003
  }
6004
+ function normalizeAssistantCompactTimeUnit(raw) {
6005
+ var normalized = String(raw || '').toLowerCase();
6006
+ if (normalized === 'm' || normalized === 'mo' || normalized === 'mos' || normalized.startsWith('month')) {
6007
+ return 'month';
6008
+ }
6009
+ if (normalized === 'min' || normalized === 'mins' || normalized.startsWith('minute')) {
6010
+ return 'minute';
6011
+ }
6012
+ if (normalized === 'h' || normalized === 'hr' || normalized === 'hrs' || normalized.startsWith('hour')) {
6013
+ return 'hour';
6014
+ }
6015
+ if (normalized === 'd' || normalized.startsWith('day')) {
6016
+ return 'day';
6017
+ }
6018
+ if (normalized === 'w' || normalized === 'wk' || normalized === 'wks' || normalized.startsWith('week')) {
6019
+ return 'week';
6020
+ }
6021
+ return 'year';
6022
+ }
5936
6023
  function parseAssistantNowRelativeToken(value) {
5937
6024
  var trimmed = normalizeOptionalString(value);
5938
6025
  if (!trimmed) {
5939
6026
  return null;
5940
6027
  }
5941
- var match = trimmed.match(ASSISTANT_NOW_RELATIVE_PATTERN);
5942
- if (!match) {
6028
+ var expandedMatch = trimmed.match(ASSISTANT_NOW_RELATIVE_PATTERN);
6029
+ if (expandedMatch) {
6030
+ var direction_1 = String(expandedMatch[1] || '').toUpperCase() === 'PLUS' ? 'PLUS' : 'MINUS';
6031
+ var amount_1 = Number(expandedMatch[2]);
6032
+ if (!Number.isFinite(amount_1) || amount_1 < 0) {
6033
+ return null;
6034
+ }
6035
+ var unit_1 = normalizeAssistantTimeUnit(expandedMatch[3] || '');
6036
+ return {
6037
+ operator: direction_1 === 'PLUS' ? '$dateAdd' : '$dateSubtract',
6038
+ amount: amount_1,
6039
+ unit: unit_1
6040
+ };
6041
+ }
6042
+ var compactMatch = trimmed.match(ASSISTANT_NOW_RELATIVE_COMPACT_PATTERN);
6043
+ if (!compactMatch) {
5943
6044
  return null;
5944
6045
  }
5945
- var direction = String(match[1] || '').toUpperCase() === 'PLUS' ? 'PLUS' : 'MINUS';
5946
- var amount = Number(match[2]);
6046
+ var direction = compactMatch[1] === '+' ? 'PLUS' : 'MINUS';
6047
+ var amount = Number(compactMatch[2]);
5947
6048
  if (!Number.isFinite(amount) || amount < 0) {
5948
6049
  return null;
5949
6050
  }
5950
- var unit = normalizeAssistantTimeUnit(match[3] || '');
6051
+ var unit = normalizeAssistantCompactTimeUnit(compactMatch[3] || '');
5951
6052
  return {
5952
6053
  operator: direction === 'PLUS' ? '$dateAdd' : '$dateSubtract',
5953
6054
  amount: amount,
@@ -9112,7 +9213,62 @@ function resolveCodexFallbackModels(config, primaryModel) {
9112
9213
  }
9113
9214
  return models;
9114
9215
  }
9115
- function resolveCodexThoughtLevel() {
9216
+ var CODEX_THOUGHT_LEVEL_VALUES = ['minimal', 'low', 'medium', 'high', 'xhigh'];
9217
+ function normalizeCodexThoughtLevel(value) {
9218
+ var normalized = normalizeOptionalString(value).toLowerCase();
9219
+ if (!normalized) {
9220
+ return undefined;
9221
+ }
9222
+ if (CODEX_THOUGHT_LEVEL_VALUES.includes(normalized)) {
9223
+ return normalized;
9224
+ }
9225
+ return undefined;
9226
+ }
9227
+ function resolveConfiguredCodexAutoThoughtLevel(kind) {
9228
+ var config = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
9229
+ var levelKey = kind === 'simple' ? 'SIMPLE' : 'COMPLEX';
9230
+ var fallbackLevel = kind === 'simple' ? 'medium' : 'high';
9231
+ var configured = normalizeCodexThoughtLevel(config["AI_ASSISTANT_CODEX_".concat(levelKey, "_THOUGHT_LEVEL")]
9232
+ || process.env["AI_ASSISTANT_CODEX_".concat(levelKey, "_THOUGHT_LEVEL")]
9233
+ || config["AI_TERMINAL_CODEX_".concat(levelKey, "_THOUGHT_LEVEL")]
9234
+ || process.env["AI_TERMINAL_CODEX_".concat(levelKey, "_THOUGHT_LEVEL")]
9235
+ || config["AI_DASHBOARD_CODEX_".concat(levelKey, "_THOUGHT_LEVEL")]
9236
+ || process.env["AI_DASHBOARD_CODEX_".concat(levelKey, "_THOUGHT_LEVEL")]);
9237
+ return configured || fallbackLevel;
9238
+ }
9239
+ function resolveAutoCodexThoughtLevel(params) {
9240
+ var combinedText = [
9241
+ normalizeOptionalString(params === null || params === void 0 ? void 0 : params.message),
9242
+ normalizeOptionalString(params === null || params === void 0 ? void 0 : params.attachmentText)
9243
+ ].filter(Boolean).join('\n').toLowerCase();
9244
+ var simpleLevel = resolveConfiguredCodexAutoThoughtLevel('simple');
9245
+ var complexLevel = resolveConfiguredCodexAutoThoughtLevel('complex');
9246
+ if (!combinedText) {
9247
+ return simpleLevel;
9248
+ }
9249
+ var bugOrIssuePatterns = [
9250
+ /\bbug\b/i,
9251
+ /\bissue\b/i,
9252
+ /\berror\b/i,
9253
+ /\bexception\b/i,
9254
+ /\bfail(?:ed|ing|ure)?\b/i,
9255
+ /\bbroken\b/i,
9256
+ /\bnot\s+working\b/i,
9257
+ /\bdoesn['’]t\s+work\b/i,
9258
+ /\bwhy\s+is\s+this\s+happening\b/i,
9259
+ /\broot\s+cause\b/i,
9260
+ /\bregression\b/i,
9261
+ /\bdebug\b/i,
9262
+ /\binvestigat(?:e|ion)\b/i,
9263
+ /\bfix\b/i,
9264
+ /\bcrash(?:ed|ing)?\b/i,
9265
+ /\btimeout\b/i,
9266
+ /\bwrong\b/i,
9267
+ /\bincorrect\b/i
9268
+ ];
9269
+ return bugOrIssuePatterns.some(function (pattern) { return pattern.test(combinedText); }) ? complexLevel : simpleLevel;
9270
+ }
9271
+ function resolveCodexThoughtLevel(params) {
9116
9272
  var config = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
9117
9273
  var raw = normalizeOptionalString(config['AI_ASSISTANT_CODEX_THOUGHT_LEVEL']
9118
9274
  || process.env.AI_ASSISTANT_CODEX_THOUGHT_LEVEL
@@ -9121,10 +9277,14 @@ function resolveCodexThoughtLevel() {
9121
9277
  || config['AI_DASHBOARD_CODEX_THOUGHT_LEVEL']
9122
9278
  || process.env.AI_DASHBOARD_CODEX_THOUGHT_LEVEL);
9123
9279
  var normalized = (raw || '').trim().toLowerCase();
9124
- if (normalized === 'minimal' || normalized === 'low' || normalized === 'medium' || normalized === 'high' || normalized === 'xhigh') {
9125
- return normalized;
9280
+ var explicitLevel = normalizeCodexThoughtLevel(normalized);
9281
+ if (explicitLevel) {
9282
+ return explicitLevel;
9283
+ }
9284
+ if (normalized === 'auto' || !normalized) {
9285
+ return resolveAutoCodexThoughtLevel(params);
9126
9286
  }
9127
- return 'low';
9287
+ return 'medium';
9128
9288
  }
9129
9289
  function resolveCodexSettings(options) {
9130
9290
  var serverConfig = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};