@resolveio/server-lib 22.1.5 → 22.1.7

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.
@@ -111,6 +111,7 @@ exports.executeAiAssistantMongoAggregate = executeAiAssistantMongoAggregate;
111
111
  exports.extractAssistantMongoDirective = extractAssistantMongoDirective;
112
112
  exports.buildAssistantInvoiceCustomerLabelExpr = buildAssistantInvoiceCustomerLabelExpr;
113
113
  exports.buildAssistantDatedPivotDisplay = buildAssistantDatedPivotDisplay;
114
+ exports.deriveAssistantCommandExecutionStatus = deriveAssistantCommandExecutionStatus;
114
115
  exports.normalizeIdsForTargetField = normalizeIdsForTargetField;
115
116
  exports.serializeMongoValue = serializeMongoValue;
116
117
  exports.flattenForTable = flattenForTable;
@@ -130,7 +131,9 @@ exports.resolveAssistantAvailableCrossCollectionFallbacksFromNames = resolveAssi
130
131
  exports.collectUserViewPermissions = collectUserViewPermissions;
131
132
  exports.userHasInvoiceAccess = userHasInvoiceAccess;
132
133
  exports.resolveAssistantUserAccessTier = resolveAssistantUserAccessTier;
134
+ exports.resolveCodexThoughtLevel = resolveCodexThoughtLevel;
133
135
  exports.classifyAssistantRequestType = classifyAssistantRequestType;
136
+ exports.shouldRunAssistantPlanner = shouldRunAssistantPlanner;
134
137
  exports.collectAssistantAllowedRoutesForUser = collectAssistantAllowedRoutesForUser;
135
138
  exports.rankAssistantNavigationRoutes = rankAssistantNavigationRoutes;
136
139
  exports.shouldUseAssistantNavigationFastPath = shouldUseAssistantNavigationFastPath;
@@ -245,6 +248,9 @@ var AI_ASSISTANT_DATE_EXPANSION_SCHEMA_MAX_FIELDS = 12;
245
248
  var execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
246
249
  var AI_ASSISTANT_CHANGE_HISTORY_DEFAULT_LIMIT = 10;
247
250
  var AI_ASSISTANT_CHANGE_HISTORY_MAX_LIMIT = 40;
251
+ var AI_ASSISTANT_CHANGE_HISTORY_MIN_DEPTH = 80;
252
+ var AI_ASSISTANT_CHANGE_HISTORY_MAX_DEPTH = 240;
253
+ var AI_ASSISTANT_CHANGE_HISTORY_DURATION_MAX_DEPTH = 1200;
248
254
  var AI_ASSISTANT_GIT_COMMAND_TIMEOUT_MS = 15000;
249
255
  var AI_ASSISTANT_BLOCKED_COLLECTIONS = new Set([
250
256
  'user-groups',
@@ -463,6 +469,9 @@ var AI_ASSISTANT_REPORT_BUILDER_EXPERT_PLAYBOOK = [
463
469
  '- Re-check collection and date fields (date_created/createdAt/date_completed/date_paid variants).',
464
470
  '- Run tiny probe (limit 1-3) to validate shape before concluding "no data".',
465
471
  '- For name filters, verify date-only first; then apply tokenized regex and id/name lookup fallback.',
472
+ '- If the user is super admin OR has permission for the requested module/view, continue best-effort retries across related collections, aliases, and field/date fallbacks before failing.',
473
+ '- Treat "collection not configured" as a retry signal, not a terminal result. Keep searching relatable collections until retry candidates are exhausted.',
474
+ '- Only stop retrying when candidate collections, scoped probes, and schema/date/name fallback paths are exhausted.',
466
475
  '',
467
476
  '7) Output behavior after bridge response.',
468
477
  '- Summarize the answer first in plain language.',
@@ -493,6 +502,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
493
502
  '- Do not guess or invent collections/fields. If unsure, verify in the codebase or run a small REPORT_BUILDER_READ probe (limit 1-5) to learn the shape.',
494
503
  '- Prefer running a small REPORT_BUILDER_READ probe over asking multiple questions.',
495
504
  '- For any data request (counts, lists, breakdowns, recent/last items), you MUST run a REPORT_BUILDER_READ or REPORT_BUILDER_AGG before answering.',
505
+ '- If the user is super admin or has permission for the requested data scope, keep attempting related collection/field fallbacks and probe reads until retry paths are exhausted; do not stop on first collection mismatch.',
496
506
  '- Ask at most one clarifying question only when required to run a query or resolve missing details.',
497
507
  '- If a field starts with id_ and refers to another collection, treat it as a foreign key and look up the related record when needed.',
498
508
  '- When resolving id_* fields, prefer lookup definitions from collection schemas/report-builder lookup tables to choose the target collection and name fields.',
@@ -563,6 +573,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
563
573
  '- Use REPORT_BUILDER_READ/REPORT_BUILDER_AGG only to produce summaries/snapshots/health checks (not raw dumps) when permitted.',
564
574
  '- If the user explicitly asks for IDs, set options.includeIds: true.',
565
575
  '- If a data question returns zero results, verify the collection/date field with a tiny read (limit 1-5) or a date field fallback before concluding there is no data.',
576
+ '- Never return "dataset not configured" as the final answer when data access is allowed; continue retries and only report failure after accessible retry paths are exhausted.',
566
577
  '- Keep responses concise and use the configured reasoning effort level (default low).',
567
578
  '- Never show internal placeholders like $$NOW in user-facing text; always use concrete dates.',
568
579
  '',
@@ -587,6 +598,7 @@ var AI_ASSISTANT_PLANNER_SYSTEM_PROMPT = [
587
598
  ' - customer_portal: apply customer scope (id_customer or other.id_customer) to all data plans.',
588
599
  ' - client_user: apply client scope (id_client) to all data plans.',
589
600
  ' - Never propose querying blocked/sensitive collections if the user lacks permission.',
601
+ ' - If permission allows a data request, plan best-effort retrieval with preferred + fallback collections and schema/date/name validation steps before concluding failure.',
590
602
  '',
591
603
  '4) PERMISSION MATCHING:',
592
604
  ' - Do NOT hardcode invoice access to "/report-builder/*".',
@@ -1616,7 +1628,7 @@ function executeAiAssistantCodexRun(payload, context) {
1616
1628
  insertResult = _e.sent();
1617
1629
  assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
1618
1630
  enqueueAssistantCodexRun(function () { return __awaiter(_this, void 0, void 0, function () {
1619
- var runStart, steps, recordStep, progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, requestClassification, dataQuestion, lastDirective, heuristicDirectivePrecomputed, usedDeterministicHeuristicFastPath, requestedTimeGrain, requestedBreakdownDimensions, enforceDatedDirective, enforceGroupedDirective, datedDirectiveRetryUsed, datedDirectiveResolved, toolResponseDebug, toolError, termHints, collectionHints, fieldHints, collectionTokenization, collectionRanking, collectionSelection, collectionOverride, collectionNames, plannerEnabled, plannerUsed, plannerOutput, plannerRaw, timingBreakdown, codexUsage, accumulateCodexUsage, contextRoute, contextMode, hintSeed, termExpansion, hintText, baseTokens, expandedTokens, baseWeights, expandedWeights, dbName, db, _a, routeHints, rankedCollections, hintCollections, assistantContext, hasDeterministicHeuristicFastPath, prompt_1, workspaceRoot, codexConfig, runOptions, shouldRunPlanner, plannerPrompt, plannerStart, _b, preferListDirective, directiveStyleHint, directivePromptMode, responseText, directiveText, directive, heuristicDirectiveFastPath, directivePrompt, directiveStart, forcedDirective, _c, initialStart, extractedDirective, error_2, directivePrompt, forcedStart, forcedDirective, _d, strictDirectivePrompt, strictStart, strictDirectiveText, strictDirective, strictDirectiveIsDated, shouldUseStrictDirective, _e, guardDirectivePrompt, guardStart, guardDirectiveText, guardDirective, _f, groupedDirectivePrompt, groupedStart, groupedDirectiveText, groupedDirective, _g, heuristicDirective, requestedCollection, cleanedResponseText, effectiveDirective, toolRequest, toolStart, toolResponse, _h, toolPayload, skipFollowupCodex, followupPrompt, followupStart, followupText, _j, error_3, error_4, finishedAt, finalNow, finishedAt, codexMs, draftingMs, finalMetadata, finalUsage, usageClientId, usageError_1, finalAssistantDoc, setPayload;
1631
+ var runStart, steps, recordStep, progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, requestClassification, dataQuestion, lastDirective, heuristicDirectivePrecomputed, usedDeterministicHeuristicFastPath, requestedTimeGrain, requestedBreakdownDimensions, enforceDatedDirective, enforceGroupedDirective, datedDirectiveRetryUsed, datedDirectiveResolved, toolResponseDebug, toolError, termHints, collectionHints, fieldHints, collectionTokenization, collectionRanking, collectionSelection, collectionOverride, collectionNames, plannerEnabled, plannerUsed, plannerSkipReason, plannerOutput, plannerRaw, timingBreakdown, codexUsage, accumulateCodexUsage, contextRoute, contextMode, hintSeed, termExpansion, hintText, baseTokens, expandedTokens, baseWeights, expandedWeights, dbName, db, _a, routeHints, rankedCollections, hintCollections, assistantContext, hasDeterministicHeuristicFastPath, prompt_1, workspaceRoot, codexConfig, runOptions, plannerRunOptions, shouldRunPlanner, plannerPrompt, plannerStart, _b, preferListDirective, directiveStyleHint, directivePromptMode, responseText, directiveText, directive, heuristicDirectiveFastPath, directivePrompt, directiveStart, forcedDirective, _c, initialStart, extractedDirective, error_2, directivePrompt, forcedStart, forcedDirective, _d, strictDirectivePrompt, strictStart, strictDirectiveText, strictDirective, strictDirectiveIsDated, shouldUseStrictDirective, _e, guardDirectivePrompt, guardStart, guardDirectiveText, guardDirective, _f, groupedDirectivePrompt, groupedStart, groupedDirectiveText, groupedDirective, _g, heuristicDirective, requestedCollection, cleanedResponseText, effectiveDirective, toolRequest, toolStart, toolResponse, _h, toolPayload, skipFollowupCodex, followupPrompt, followupStart, followupText, _j, error_3, error_4, finishedAt, finalNow, finishedAt, codexMs, draftingMs, finalMetadata, finalUsage, usageClientId, usageError_1, finalAssistantDoc, setPayload;
1620
1632
  var _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12;
1621
1633
  return __generator(this, function (_13) {
1622
1634
  switch (_13.label) {
@@ -1671,6 +1683,7 @@ function executeAiAssistantCodexRun(payload, context) {
1671
1683
  collectionNames = [];
1672
1684
  plannerEnabled = resolveAssistantPlannerEnabled();
1673
1685
  plannerUsed = false;
1686
+ plannerSkipReason = '';
1674
1687
  plannerOutput = null;
1675
1688
  plannerRaw = '';
1676
1689
  timingBreakdown = {
@@ -1706,7 +1719,7 @@ function executeAiAssistantCodexRun(payload, context) {
1706
1719
  });
1707
1720
  _13.label = 1;
1708
1721
  case 1:
1709
- _13.trys.push([1, 49, 50, 51]);
1722
+ _13.trys.push([1, 51, 52, 53]);
1710
1723
  hintSeed = [message, contextRoute].filter(Boolean).join(' ');
1711
1724
  termExpansion = expandAssistantTermSynonyms(hintSeed);
1712
1725
  hintText = termExpansion.expanded || hintSeed;
@@ -1804,7 +1817,8 @@ function executeAiAssistantCodexRun(payload, context) {
1804
1817
  skipGitRepoCheck: true,
1805
1818
  modelReasoningEffort: resolveCodexThoughtLevel({
1806
1819
  message: message,
1807
- attachmentText: attachmentData.promptText
1820
+ attachmentText: attachmentData.promptText,
1821
+ requestType: requestClassification.type
1808
1822
  }),
1809
1823
  networkAccessEnabled: false,
1810
1824
  webSearchMode: 'disabled',
@@ -1812,10 +1826,13 @@ function executeAiAssistantCodexRun(payload, context) {
1812
1826
  approvalPolicy: 'never'
1813
1827
  }
1814
1828
  };
1815
- shouldRunPlanner = plannerEnabled
1816
- && !(requestClassification.type === 'navigation' && !dataQuestion)
1817
- && !hasDeterministicHeuristicFastPath;
1818
- if (!shouldRunPlanner) return [3 /*break*/, 10];
1829
+ plannerRunOptions = __assign(__assign({}, runOptions), { threadOptions: __assign(__assign({}, (runOptions.threadOptions || {})), { modelReasoningEffort: 'minimal' }) });
1830
+ shouldRunPlanner = shouldRunAssistantPlanner({
1831
+ plannerEnabled: plannerEnabled,
1832
+ requestClassification: requestClassification,
1833
+ hasDeterministicHeuristicFastPath: hasDeterministicHeuristicFastPath
1834
+ });
1835
+ if (!shouldRunPlanner) return [3 /*break*/, 11];
1819
1836
  plannerUsed = true;
1820
1837
  recordStep('Planning: planner prompt');
1821
1838
  plannerPrompt = buildAssistantPlannerPrompt({
@@ -1832,7 +1849,7 @@ function executeAiAssistantCodexRun(payload, context) {
1832
1849
  case 7:
1833
1850
  _13.trys.push([7, 9, , 10]);
1834
1851
  plannerStart = Date.now();
1835
- return [4 /*yield*/, runCodexInWorkerThread(plannerPrompt, runOptions, codexConfig, streamProgress)];
1852
+ return [4 /*yield*/, runCodexInWorkerThread(plannerPrompt, plannerRunOptions, codexConfig, streamProgress)];
1836
1853
  case 8:
1837
1854
  plannerRaw = _13.sent();
1838
1855
  accumulateCodexUsage(plannerPrompt, plannerRaw);
@@ -1844,7 +1861,22 @@ function executeAiAssistantCodexRun(payload, context) {
1844
1861
  _b = _13.sent();
1845
1862
  recordStep('Planning: planner result', { parsed: false });
1846
1863
  return [3 /*break*/, 10];
1847
- case 10:
1864
+ case 10: return [3 /*break*/, 12];
1865
+ case 11:
1866
+ if (plannerEnabled) {
1867
+ if (hasDeterministicHeuristicFastPath) {
1868
+ plannerSkipReason = 'heuristic_directive_fast_path';
1869
+ }
1870
+ else if (!requestClassification.dataQuestion) {
1871
+ plannerSkipReason = "non_data_".concat(requestClassification.type || 'unknown');
1872
+ }
1873
+ else {
1874
+ plannerSkipReason = 'policy';
1875
+ }
1876
+ recordStep('Planning: planner skipped', { reason: plannerSkipReason });
1877
+ }
1878
+ _13.label = 12;
1879
+ case 12:
1848
1880
  requestClassification = classifyAssistantRequestType(message, plannerOutput || undefined);
1849
1881
  dataQuestion = requestClassification.dataQuestion;
1850
1882
  requestedTimeGrain = resolveAssistantRequestedTimeGrain(message, plannerOutput || undefined);
@@ -1895,15 +1927,15 @@ function executeAiAssistantCodexRun(payload, context) {
1895
1927
  timeGrain: requestedTimeGrain || undefined
1896
1928
  });
1897
1929
  }
1898
- if (!(dataQuestion && !directive)) return [3 /*break*/, 14];
1930
+ if (!(dataQuestion && !directive)) return [3 /*break*/, 16];
1899
1931
  recordStep('Directive: determine tool', { type: 'data-question' });
1900
1932
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, directiveStyleHint, directivePromptMode);
1901
- _13.label = 11;
1902
- case 11:
1903
- _13.trys.push([11, 13, , 14]);
1933
+ _13.label = 13;
1934
+ case 13:
1935
+ _13.trys.push([13, 15, , 16]);
1904
1936
  directiveStart = Date.now();
1905
1937
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1906
- case 12:
1938
+ case 14:
1907
1939
  directiveText = _13.sent();
1908
1940
  accumulateCodexUsage(directivePrompt, directiveText);
1909
1941
  timingBreakdown.directiveMs = Date.now() - directiveStart;
@@ -1920,19 +1952,19 @@ function executeAiAssistantCodexRun(payload, context) {
1920
1952
  permissionView: normalizeOptionalString((_t = directive.payload) === null || _t === void 0 ? void 0 : _t.permissionView) || undefined
1921
1953
  });
1922
1954
  }
1923
- return [3 /*break*/, 14];
1924
- case 13:
1955
+ return [3 /*break*/, 16];
1956
+ case 15:
1925
1957
  _c = _13.sent();
1926
- return [3 /*break*/, 14];
1927
- case 14:
1928
- if (!(!directive && !dataQuestion)) return [3 /*break*/, 18];
1958
+ return [3 /*break*/, 16];
1959
+ case 16:
1960
+ if (!(!directive && !dataQuestion)) return [3 /*break*/, 20];
1929
1961
  recordStep('Response: draft initial answer', { mode: 'full' });
1930
- _13.label = 15;
1931
- case 15:
1932
- _13.trys.push([15, 17, , 18]);
1962
+ _13.label = 17;
1963
+ case 17:
1964
+ _13.trys.push([17, 19, , 20]);
1933
1965
  initialStart = Date.now();
1934
1966
  return [4 /*yield*/, runCodexInWorkerThread(prompt_1, runOptions, codexConfig, streamProgress)];
1935
- case 16:
1967
+ case 18:
1936
1968
  responseText = _13.sent();
1937
1969
  accumulateCodexUsage(prompt_1, responseText);
1938
1970
  timingBreakdown.initialResponseMs = Date.now() - initialStart;
@@ -1949,23 +1981,23 @@ function executeAiAssistantCodexRun(payload, context) {
1949
1981
  permissionView: normalizeOptionalString((_w = directive.payload) === null || _w === void 0 ? void 0 : _w.permissionView) || undefined
1950
1982
  });
1951
1983
  }
1952
- return [3 /*break*/, 18];
1953
- case 17:
1984
+ return [3 /*break*/, 20];
1985
+ case 19:
1954
1986
  error_2 = _13.sent();
1955
1987
  recordStep('Response: initial draft failed', {
1956
1988
  message: normalizeOptionalString(error_2 === null || error_2 === void 0 ? void 0 : error_2.message) || 'Unknown error'
1957
1989
  });
1958
- return [3 /*break*/, 18];
1959
- case 18:
1960
- if (!(!directive && dataQuestion)) return [3 /*break*/, 22];
1990
+ return [3 /*break*/, 20];
1991
+ case 20:
1992
+ if (!(!directive && dataQuestion)) return [3 /*break*/, 24];
1961
1993
  recordStep('Directive: forced retry', { mode: 'directive-only' });
1962
1994
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, directiveStyleHint, directivePromptMode);
1963
- _13.label = 19;
1964
- case 19:
1965
- _13.trys.push([19, 21, , 22]);
1995
+ _13.label = 21;
1996
+ case 21:
1997
+ _13.trys.push([21, 23, , 24]);
1966
1998
  forcedStart = Date.now();
1967
1999
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1968
- case 20:
2000
+ case 22:
1969
2001
  directiveText = _13.sent();
1970
2002
  accumulateCodexUsage(directivePrompt, directiveText);
1971
2003
  timingBreakdown.forcedDirectiveMs = Date.now() - forcedStart;
@@ -1982,15 +2014,15 @@ function executeAiAssistantCodexRun(payload, context) {
1982
2014
  permissionView: normalizeOptionalString((_z = directive.payload) === null || _z === void 0 ? void 0 : _z.permissionView) || undefined
1983
2015
  });
1984
2016
  }
1985
- return [3 /*break*/, 22];
1986
- case 21:
2017
+ return [3 /*break*/, 24];
2018
+ case 23:
1987
2019
  _d = _13.sent();
1988
- return [3 /*break*/, 22];
1989
- case 22:
2020
+ return [3 /*break*/, 24];
2021
+ case 24:
1990
2022
  if (!(directive
1991
2023
  && enforceDatedDirective
1992
2024
  && !isAssistantDeterministicHeuristicDirective(directive)
1993
- && !isAssistantDirectiveDated(directive))) return [3 /*break*/, 26];
2025
+ && !isAssistantDirectiveDated(directive))) return [3 /*break*/, 28];
1994
2026
  recordStep('Directive: dated retry', {
1995
2027
  currentType: directive.type,
1996
2028
  timeGrain: requestedTimeGrain || undefined
@@ -2002,12 +2034,12 @@ function executeAiAssistantCodexRun(payload, context) {
2002
2034
  requestedBreakdowns: requestedBreakdownDimensions,
2003
2035
  strict: true
2004
2036
  }), 'aggregate_only');
2005
- _13.label = 23;
2006
- case 23:
2007
- _13.trys.push([23, 25, , 26]);
2037
+ _13.label = 25;
2038
+ case 25:
2039
+ _13.trys.push([25, 27, , 28]);
2008
2040
  strictStart = Date.now();
2009
2041
  return [4 /*yield*/, runCodexInWorkerThread(strictDirectivePrompt, runOptions, codexConfig, streamProgress)];
2010
- case 24:
2042
+ case 26:
2011
2043
  strictDirectiveText = _13.sent();
2012
2044
  accumulateCodexUsage(strictDirectivePrompt, strictDirectiveText);
2013
2045
  timingBreakdown.forcedDirectiveMs += Date.now() - strictStart;
@@ -2029,15 +2061,15 @@ function executeAiAssistantCodexRun(payload, context) {
2029
2061
  timeGrain: requestedTimeGrain || undefined
2030
2062
  });
2031
2063
  }
2032
- return [3 /*break*/, 26];
2033
- case 25:
2064
+ return [3 /*break*/, 28];
2065
+ case 27:
2034
2066
  _e = _13.sent();
2035
- return [3 /*break*/, 26];
2036
- case 26:
2067
+ return [3 /*break*/, 28];
2068
+ case 28:
2037
2069
  if (!(directive
2038
2070
  && enforceDatedDirective
2039
2071
  && !isAssistantDeterministicHeuristicDirective(directive)
2040
- && directive.type === 'read')) return [3 /*break*/, 30];
2072
+ && directive.type === 'read')) return [3 /*break*/, 32];
2041
2073
  recordStep('Directive: dated guard retry', {
2042
2074
  currentType: directive.type,
2043
2075
  timeGrain: requestedTimeGrain || undefined
@@ -2049,12 +2081,12 @@ function executeAiAssistantCodexRun(payload, context) {
2049
2081
  requestedBreakdowns: requestedBreakdownDimensions,
2050
2082
  strict: true
2051
2083
  }), 'aggregate_only');
2052
- _13.label = 27;
2053
- case 27:
2054
- _13.trys.push([27, 29, , 30]);
2084
+ _13.label = 29;
2085
+ case 29:
2086
+ _13.trys.push([29, 31, , 32]);
2055
2087
  guardStart = Date.now();
2056
2088
  return [4 /*yield*/, runCodexInWorkerThread(guardDirectivePrompt, runOptions, codexConfig, streamProgress)];
2057
- case 28:
2089
+ case 30:
2058
2090
  guardDirectiveText = _13.sent();
2059
2091
  accumulateCodexUsage(guardDirectivePrompt, guardDirectiveText);
2060
2092
  timingBreakdown.forcedDirectiveMs += Date.now() - guardStart;
@@ -2074,15 +2106,15 @@ function executeAiAssistantCodexRun(payload, context) {
2074
2106
  timeGrain: requestedTimeGrain || undefined
2075
2107
  });
2076
2108
  }
2077
- return [3 /*break*/, 30];
2078
- case 29:
2109
+ return [3 /*break*/, 32];
2110
+ case 31:
2079
2111
  _f = _13.sent();
2080
- return [3 /*break*/, 30];
2081
- case 30:
2112
+ return [3 /*break*/, 32];
2113
+ case 32:
2082
2114
  if (!(directive
2083
2115
  && enforceGroupedDirective
2084
2116
  && !isAssistantDeterministicHeuristicDirective(directive)
2085
- && !isAssistantDirectiveGrouped(directive))) return [3 /*break*/, 34];
2117
+ && !isAssistantDirectiveGrouped(directive))) return [3 /*break*/, 36];
2086
2118
  recordStep('Directive: grouped guard retry', {
2087
2119
  currentType: directive.type,
2088
2120
  breakdownDimensions: requestedBreakdownDimensions.length ? requestedBreakdownDimensions : undefined
@@ -2094,12 +2126,12 @@ function executeAiAssistantCodexRun(payload, context) {
2094
2126
  requestedBreakdowns: requestedBreakdownDimensions,
2095
2127
  strict: true
2096
2128
  }), 'aggregate_only');
2097
- _13.label = 31;
2098
- case 31:
2099
- _13.trys.push([31, 33, , 34]);
2129
+ _13.label = 33;
2130
+ case 33:
2131
+ _13.trys.push([33, 35, , 36]);
2100
2132
  groupedStart = Date.now();
2101
2133
  return [4 /*yield*/, runCodexInWorkerThread(groupedDirectivePrompt, runOptions, codexConfig, streamProgress)];
2102
- case 32:
2134
+ case 34:
2103
2135
  groupedDirectiveText = _13.sent();
2104
2136
  accumulateCodexUsage(groupedDirectivePrompt, groupedDirectiveText);
2105
2137
  timingBreakdown.forcedDirectiveMs += Date.now() - groupedStart;
@@ -2122,11 +2154,11 @@ function executeAiAssistantCodexRun(payload, context) {
2122
2154
  timeGrain: requestedTimeGrain || undefined
2123
2155
  });
2124
2156
  }
2125
- return [3 /*break*/, 34];
2126
- case 33:
2157
+ return [3 /*break*/, 36];
2158
+ case 35:
2127
2159
  _g = _13.sent();
2128
- return [3 /*break*/, 34];
2129
- case 34:
2160
+ return [3 /*break*/, 36];
2161
+ case 36:
2130
2162
  if (!directive && dataQuestion) {
2131
2163
  heuristicDirective = buildAssistantHeuristicDirective(message, collectionHints);
2132
2164
  if (isAssistantExecutableDirective(heuristicDirective)) {
@@ -2165,7 +2197,7 @@ function executeAiAssistantCodexRun(payload, context) {
2165
2197
  if (cleanedResponseText) {
2166
2198
  assistantContent = sanitizeAssistantResponse(cleanedResponseText);
2167
2199
  }
2168
- if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 47];
2200
+ if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 49];
2169
2201
  effectiveDirective = collectionOverride
2170
2202
  ? __assign(__assign({}, directive), { payload: __assign(__assign({}, (directive.payload || {})), { collection: collectionOverride.to }) }) : directive;
2171
2203
  toolRequest = buildAssistantToolRequest(effectiveDirective, input);
@@ -2175,20 +2207,20 @@ function executeAiAssistantCodexRun(payload, context) {
2175
2207
  collection: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.collection) || undefined,
2176
2208
  permissionView: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.permissionView) || undefined
2177
2209
  });
2178
- _13.label = 35;
2179
- case 35:
2180
- _13.trys.push([35, 45, , 46]);
2210
+ _13.label = 37;
2211
+ case 37:
2212
+ _13.trys.push([37, 47, , 48]);
2181
2213
  toolStart = Date.now();
2182
- if (!(effectiveDirective.type === 'aggregate')) return [3 /*break*/, 37];
2214
+ if (!(effectiveDirective.type === 'aggregate')) return [3 /*break*/, 39];
2183
2215
  return [4 /*yield*/, executeAiAssistantReportBuilderAggregate(toolRequest, context)];
2184
- case 36:
2185
- _h = _13.sent();
2186
- return [3 /*break*/, 39];
2187
- case 37: return [4 /*yield*/, executeAiAssistantReportBuilderRead(toolRequest, context)];
2188
2216
  case 38:
2189
2217
  _h = _13.sent();
2190
- _13.label = 39;
2191
- case 39:
2218
+ return [3 /*break*/, 41];
2219
+ case 39: return [4 /*yield*/, executeAiAssistantReportBuilderRead(toolRequest, context)];
2220
+ case 40:
2221
+ _h = _13.sent();
2222
+ _13.label = 41;
2223
+ case 41:
2192
2224
  toolResponse = _h;
2193
2225
  timingBreakdown.toolMs = Date.now() - toolStart;
2194
2226
  toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
@@ -2204,53 +2236,53 @@ function executeAiAssistantCodexRun(payload, context) {
2204
2236
  progressTracker.push('Drafting response');
2205
2237
  skipFollowupCodex = usedDeterministicHeuristicFastPath
2206
2238
  || isAssistantDeterministicHeuristicDirective(effectiveDirective);
2207
- if (!skipFollowupCodex) return [3 /*break*/, 40];
2239
+ if (!skipFollowupCodex) return [3 /*break*/, 42];
2208
2240
  recordStep('Drafting response: deterministic summary', {
2209
2241
  reason: normalizeOptionalString(effectiveDirective.rawLine) || 'deterministic_heuristic'
2210
2242
  });
2211
2243
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
2212
2244
  assistantContent = applyAssistantDisplayTableToResponse(assistantContent, toolPayload.result.output.display);
2213
- return [3 /*break*/, 44];
2214
- case 40:
2245
+ return [3 /*break*/, 46];
2246
+ case 42:
2215
2247
  recordStep('Drafting response');
2216
2248
  followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
2217
- _13.label = 41;
2218
- case 41:
2219
- _13.trys.push([41, 43, , 44]);
2249
+ _13.label = 43;
2250
+ case 43:
2251
+ _13.trys.push([43, 45, , 46]);
2220
2252
  followupStart = Date.now();
2221
2253
  return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
2222
- case 42:
2254
+ case 44:
2223
2255
  followupText = _13.sent();
2224
2256
  accumulateCodexUsage(followupPrompt, followupText);
2225
2257
  timingBreakdown.followupMs = Date.now() - followupStart;
2226
2258
  assistantContent = sanitizeAssistantResponse(followupText);
2227
2259
  assistantContent = applyAssistantDisplayTableToResponse(assistantContent, toolPayload.result.output.display);
2228
- return [3 /*break*/, 44];
2229
- case 43:
2260
+ return [3 /*break*/, 46];
2261
+ case 45:
2230
2262
  _j = _13.sent();
2231
2263
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
2232
- return [3 /*break*/, 44];
2233
- case 44: return [3 /*break*/, 46];
2234
- case 45:
2235
- error_3 = _13.sent();
2236
- assistantContent = buildAssistantToolErrorMessage(error_3);
2237
- toolError = error_3;
2238
2264
  return [3 /*break*/, 46];
2239
2265
  case 46: return [3 /*break*/, 48];
2240
2266
  case 47:
2267
+ error_3 = _13.sent();
2268
+ assistantContent = buildAssistantToolErrorMessage(error_3);
2269
+ toolError = error_3;
2270
+ return [3 /*break*/, 48];
2271
+ case 48: return [3 /*break*/, 50];
2272
+ case 49:
2241
2273
  progressTracker.push('Drafting response');
2242
2274
  recordStep('Drafting response');
2243
- _13.label = 48;
2244
- case 48: return [3 /*break*/, 51];
2245
- case 49:
2275
+ _13.label = 50;
2276
+ case 50: return [3 /*break*/, 53];
2277
+ case 51:
2246
2278
  error_4 = _13.sent();
2247
2279
  assistantContent = buildAssistantCodexErrorMessage(error_4);
2248
2280
  recordStep('Error', { message: normalizeOptionalString(error_4 === null || error_4 === void 0 ? void 0 : error_4.message) || 'Unknown error' });
2249
- return [3 /*break*/, 51];
2250
- case 50:
2281
+ return [3 /*break*/, 53];
2282
+ case 52:
2251
2283
  progressTracker.stop();
2252
2284
  return [7 /*endfinally*/];
2253
- case 51:
2285
+ case 53:
2254
2286
  if (!assistantContent) {
2255
2287
  assistantContent = buildAssistantCodexErrorMessage(null);
2256
2288
  }
@@ -2320,7 +2352,7 @@ function executeAiAssistantCodexRun(payload, context) {
2320
2352
  : undefined
2321
2353
  } : (plannerEnabled ? {
2322
2354
  enabled: false,
2323
- reason: 'skipped_for_navigation'
2355
+ reason: plannerSkipReason || 'skipped_by_policy'
2324
2356
  } : undefined)
2325
2357
  },
2326
2358
  timings: {
@@ -2346,14 +2378,14 @@ function executeAiAssistantCodexRun(payload, context) {
2346
2378
  output_tokens: codexUsage.output_tokens,
2347
2379
  total_tokens: codexUsage.total_tokens
2348
2380
  } : null;
2349
- if (!finalUsage) return [3 /*break*/, 56];
2381
+ if (!finalUsage) return [3 /*break*/, 58];
2350
2382
  return [4 /*yield*/, resolveClientId(conversation, input.id_client, context === null || context === void 0 ? void 0 : context.id_user)];
2351
- case 52:
2383
+ case 54:
2352
2384
  usageClientId = _13.sent();
2353
- if (!usageClientId) return [3 /*break*/, 56];
2354
- _13.label = 53;
2355
- case 53:
2356
- _13.trys.push([53, 55, , 56]);
2385
+ if (!usageClientId) return [3 /*break*/, 58];
2386
+ _13.label = 55;
2387
+ case 55:
2388
+ _13.trys.push([55, 57, , 58]);
2357
2389
  return [4 /*yield*/, (0, openai_usage_ledger_manager_1.recordOpenAIUsage)({
2358
2390
  id_client: usageClientId,
2359
2391
  model: finalUsage.model,
@@ -2364,16 +2396,16 @@ function executeAiAssistantCodexRun(payload, context) {
2364
2396
  id_request: requestId || undefined,
2365
2397
  id_conversation: conversation._id
2366
2398
  })];
2367
- case 54:
2399
+ case 56:
2368
2400
  _13.sent();
2369
- return [3 /*break*/, 56];
2370
- case 55:
2401
+ return [3 /*break*/, 58];
2402
+ case 57:
2371
2403
  usageError_1 = _13.sent();
2372
2404
  console.error(new Date(), 'Failed to record codex usage', usageError_1);
2373
- return [3 /*break*/, 56];
2374
- case 56:
2405
+ return [3 /*break*/, 58];
2406
+ case 58:
2375
2407
  finalAssistantDoc = __assign(__assign(__assign(__assign({}, assistantDoc), { _id: assistantMessageId, content: assistantContent, metadata: finalMetadata }), (finalUsage ? { usage: finalUsage } : {})), { updatedAt: finalNow });
2376
- if (!assistantMessageId) return [3 /*break*/, 58];
2408
+ if (!assistantMessageId) return [3 /*break*/, 60];
2377
2409
  setPayload = {
2378
2410
  content: assistantContent,
2379
2411
  metadata: finalMetadata,
@@ -2383,18 +2415,18 @@ function executeAiAssistantCodexRun(payload, context) {
2383
2415
  setPayload.usage = finalUsage;
2384
2416
  }
2385
2417
  return [4 /*yield*/, updateAssistantMessageWithFallback(assistantMessageId, setPayload)];
2386
- case 57:
2387
- _13.sent();
2388
- _13.label = 58;
2389
- case 58: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
2390
2418
  case 59:
2391
2419
  _13.sent();
2392
- if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 61];
2420
+ _13.label = 60;
2421
+ case 60: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
2422
+ case 61:
2423
+ _13.sent();
2424
+ if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 63];
2393
2425
  return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
2394
- case 60:
2426
+ case 62:
2395
2427
  _13.sent();
2396
- _13.label = 61;
2397
- case 61: return [2 /*return*/, finalAssistantDoc];
2428
+ _13.label = 63;
2429
+ case 63: return [2 /*return*/, finalAssistantDoc];
2398
2430
  }
2399
2431
  });
2400
2432
  }); });
@@ -6951,8 +6983,11 @@ function buildAssistantToolErrorMessage(error) {
6951
6983
  if (normalized.includes('unrecognized argument to $datesubtract:') || normalized.includes('unrecognized argument to $dateadd:')) {
6952
6984
  return 'The data query failed because of an invalid date expression argument. Please retry; date arithmetic arguments are now normalized automatically.';
6953
6985
  }
6986
+ if (normalized.includes('no queryable collection could be resolved')) {
6987
+ return 'I tried all accessible related datasets but could not resolve a queryable source for this request.';
6988
+ }
6954
6989
  if (normalized.includes('report builder bridge') && normalized.includes('not configured')) {
6955
- return 'That dataset is not configured for assistant data access yet.';
6990
+ return 'I tried all accessible related datasets but could not resolve a queryable source for this request.';
6956
6991
  }
6957
6992
  if (normalized.includes('collection is required')) {
6958
6993
  return 'I need a valid collection to read from. Please specify which screen or dataset you want.';
@@ -6962,8 +6997,27 @@ function buildAssistantToolErrorMessage(error) {
6962
6997
  }
6963
6998
  return 'I couldn\'t run the requested data query.';
6964
6999
  }
7000
+ function deriveAssistantCommandExecutionStatus(commandValue) {
7001
+ var command = normalizeOptionalString(commandValue).toLowerCase();
7002
+ if (!command) {
7003
+ return 'Running command';
7004
+ }
7005
+ if (/\b(rg|grep|ripgrep|ag|ack)\b/.test(command)) {
7006
+ return 'Searching files';
7007
+ }
7008
+ if (/\bfind\b/.test(command)) {
7009
+ return 'Finding files';
7010
+ }
7011
+ if (/\b(cat|sed|awk|head|tail|less|more)\b/.test(command)) {
7012
+ return 'Opening files';
7013
+ }
7014
+ if (/\b(ls|tree)\b/.test(command)) {
7015
+ return 'Scanning files';
7016
+ }
7017
+ return 'Running command';
7018
+ }
6965
7019
  function deriveAssistantStreamStatus(event) {
6966
- var _a;
7020
+ var _a, _b;
6967
7021
  if (!event || !event.type) {
6968
7022
  return null;
6969
7023
  }
@@ -6982,10 +7036,10 @@ function deriveAssistantStreamStatus(event) {
6982
7036
  return 'Planning';
6983
7037
  }
6984
7038
  if (itemType === 'command_execution') {
6985
- return 'Planning';
7039
+ return deriveAssistantCommandExecutionStatus((_b = event === null || event === void 0 ? void 0 : event.item) === null || _b === void 0 ? void 0 : _b.command);
6986
7040
  }
6987
7041
  if (itemType === 'web_search') {
6988
- return 'Planning';
7042
+ return 'Searching references';
6989
7043
  }
6990
7044
  if (itemType === 'file_change') {
6991
7045
  return 'Drafting response';
@@ -7052,7 +7106,7 @@ function updateAssistantProgress(messageId, progress) {
7052
7106
  'metadata.progress': normalized,
7053
7107
  updatedAt: new Date()
7054
7108
  }
7055
- })];
7109
+ }, undefined, false, false, true)];
7056
7110
  case 2:
7057
7111
  _b.sent();
7058
7112
  return [3 /*break*/, 4];
@@ -12430,7 +12484,7 @@ function listAssistantReportBuilderCollectionsFromManager() {
12430
12484
  }
12431
12485
  function listAssistantCollections(db, dbName) {
12432
12486
  return __awaiter(this, void 0, void 0, function () {
12433
- var cacheKey, cached, now, reportBuilderCollections, collections, names, _a;
12487
+ var cacheKey, cached, now, seen, merged, pushName, collections, _a, names;
12434
12488
  return __generator(this, function (_b) {
12435
12489
  switch (_b.label) {
12436
12490
  case 0:
@@ -12440,26 +12494,39 @@ function listAssistantCollections(db, dbName) {
12440
12494
  if (cached && now - cached.updatedAt < AI_ASSISTANT_COLLECTION_CACHE_TTL_MS) {
12441
12495
  return [2 /*return*/, cached.names];
12442
12496
  }
12443
- reportBuilderCollections = listAssistantReportBuilderCollectionsFromManager().sort(function (a, b) { return a.localeCompare(b); });
12444
- if (reportBuilderCollections.length) {
12445
- AI_ASSISTANT_COLLECTION_CACHE.set(cacheKey, { names: reportBuilderCollections, updatedAt: now });
12446
- return [2 /*return*/, reportBuilderCollections];
12447
- }
12497
+ seen = new Set();
12498
+ merged = [];
12499
+ pushName = function (name) {
12500
+ var normalized = normalizeOptionalString(name);
12501
+ if (!normalized || seen.has(normalized)) {
12502
+ return;
12503
+ }
12504
+ seen.add(normalized);
12505
+ merged.push(normalized);
12506
+ };
12507
+ listAssistantReportBuilderCollectionsFromManager().forEach(pushName);
12448
12508
  _b.label = 1;
12449
12509
  case 1:
12450
12510
  _b.trys.push([1, 3, , 4]);
12451
12511
  return [4 /*yield*/, db.listCollections({}, { nameOnly: true }).toArray()];
12452
12512
  case 2:
12453
12513
  collections = _b.sent();
12454
- names = Array.isArray(collections)
12455
- ? collections.map(function (entry) { return normalizeOptionalString(entry === null || entry === void 0 ? void 0 : entry.name); }).filter(Boolean)
12456
- : [];
12457
- AI_ASSISTANT_COLLECTION_CACHE.set(cacheKey, { names: names, updatedAt: now });
12458
- return [2 /*return*/, names];
12514
+ if (Array.isArray(collections)) {
12515
+ collections.forEach(function (entry) {
12516
+ pushName(normalizeOptionalString(entry === null || entry === void 0 ? void 0 : entry.name));
12517
+ });
12518
+ }
12519
+ return [3 /*break*/, 4];
12459
12520
  case 3:
12460
12521
  _a = _b.sent();
12522
+ return [3 /*break*/, 4];
12523
+ case 4:
12524
+ names = merged.sort(function (a, b) { return a.localeCompare(b); });
12525
+ if (names.length) {
12526
+ AI_ASSISTANT_COLLECTION_CACHE.set(cacheKey, { names: names, updatedAt: now });
12527
+ return [2 /*return*/, names];
12528
+ }
12461
12529
  return [2 /*return*/, (cached === null || cached === void 0 ? void 0 : cached.names) || []];
12462
- case 4: return [2 /*return*/];
12463
12530
  }
12464
12531
  });
12465
12532
  });
@@ -12943,6 +13010,16 @@ var AI_ASSISTANT_BRIDGE_COLLECTION_ALIASES = {
12943
13010
  supporttickets: 'support-tickets',
12944
13011
  ticket: 'support-tickets',
12945
13012
  tickets: 'support-tickets',
13013
+ timeentry: 'time_entries',
13014
+ timeentries: 'time_entries',
13015
+ timeentrylog: 'time_entries',
13016
+ timeentrylogs: 'time_entries',
13017
+ timeentryrecord: 'time_entries',
13018
+ timeentryrecords: 'time_entries',
13019
+ timesheet: 'timesheets',
13020
+ timesheets: 'timesheets',
13021
+ payrollentry: 'payroll_entries',
13022
+ payrollentries: 'payroll_entries',
12946
13023
  invoice: 'invoices',
12947
13024
  client: 'customers',
12948
13025
  clients: 'customers',
@@ -12959,7 +13036,20 @@ var AI_ASSISTANT_DIRECT_COLLECTION_FALLBACK_ALLOWLIST = new Set([
12959
13036
  'duplicate-deliveries',
12960
13037
  'third-party-drivers',
12961
13038
  'customers',
12962
- 'support-tickets'
13039
+ 'support-tickets',
13040
+ 'time_entries',
13041
+ 'time-entries',
13042
+ 'timeentries',
13043
+ 'timesheets',
13044
+ 'timesheet-entries',
13045
+ 'employee-time',
13046
+ 'employee_time',
13047
+ 'employee-time-entries',
13048
+ 'employee_time_entries',
13049
+ 'payroll_entries',
13050
+ 'payroll-entries',
13051
+ 'billing_entries',
13052
+ 'billing-entries'
12963
13053
  ]);
12964
13054
  var AI_ASSISTANT_ORDER_COLLECTION_FALLBACKS = [
12965
13055
  'work-order-dynamics',
@@ -12985,6 +13075,21 @@ var AI_ASSISTANT_INVOICE_COLLECTION_FALLBACKS = [
12985
13075
  'billings',
12986
13076
  'sales-taxes'
12987
13077
  ];
13078
+ var AI_ASSISTANT_TIME_COLLECTION_FALLBACKS = [
13079
+ 'time_entries',
13080
+ 'time-entries',
13081
+ 'timeentries',
13082
+ 'timesheets',
13083
+ 'timesheet-entries',
13084
+ 'employee-time',
13085
+ 'employee_time',
13086
+ 'employee-time-entries',
13087
+ 'employee_time_entries',
13088
+ 'payroll_entries',
13089
+ 'payroll-entries',
13090
+ 'billing_entries',
13091
+ 'billing-entries'
13092
+ ];
12988
13093
  function normalizeAssistantCollectionFamilyName(value) {
12989
13094
  var normalized = normalizeOptionalString(value).toLowerCase();
12990
13095
  if (!normalized) {
@@ -13050,6 +13155,13 @@ function resolveAssistantCrossCollectionFallbackCandidates(collection) {
13050
13155
  else if (AI_ASSISTANT_INVOICE_COLLECTION_FALLBACKS.includes(normalized) || normalized.includes('invoice') || normalized.includes('billing')) {
13051
13156
  candidates = AI_ASSISTANT_INVOICE_COLLECTION_FALLBACKS;
13052
13157
  }
13158
+ else if (AI_ASSISTANT_TIME_COLLECTION_FALLBACKS.includes(normalized)
13159
+ || normalized.includes('time')
13160
+ || normalized.includes('sheet')
13161
+ || normalized.includes('hour')
13162
+ || normalized.includes('payroll')) {
13163
+ candidates = AI_ASSISTANT_TIME_COLLECTION_FALLBACKS;
13164
+ }
13053
13165
  var deduped = [];
13054
13166
  candidates.forEach(function (candidate) {
13055
13167
  if (!candidate || deduped.includes(candidate)) {
@@ -13120,28 +13232,48 @@ function isAssistantDirectCollectionFallbackAllowed(collection) {
13120
13232
  }
13121
13233
  return AI_ASSISTANT_DIRECT_COLLECTION_FALLBACK_ALLOWLIST.has(normalized);
13122
13234
  }
13235
+ function doesAssistantCollectionExistInDb(db, collection) {
13236
+ return __awaiter(this, void 0, void 0, function () {
13237
+ var normalized, collections, _a;
13238
+ return __generator(this, function (_b) {
13239
+ switch (_b.label) {
13240
+ case 0:
13241
+ normalized = normalizeOptionalString(collection);
13242
+ if (!normalized || !db || typeof db.listCollections !== 'function') {
13243
+ return [2 /*return*/, false];
13244
+ }
13245
+ _b.label = 1;
13246
+ case 1:
13247
+ _b.trys.push([1, 3, , 4]);
13248
+ return [4 /*yield*/, db.listCollections({ name: normalized }, { nameOnly: true }).toArray()];
13249
+ case 2:
13250
+ collections = _b.sent();
13251
+ return [2 /*return*/, Array.isArray(collections)
13252
+ && collections.some(function (entry) { return normalizeOptionalString(entry === null || entry === void 0 ? void 0 : entry.name) === normalized; })];
13253
+ case 3:
13254
+ _a = _b.sent();
13255
+ return [2 /*return*/, false];
13256
+ case 4: return [2 /*return*/];
13257
+ }
13258
+ });
13259
+ });
13260
+ }
13123
13261
  function resolveAssistantReportBuilderBridgeCollection(collection_1, db_1) {
13124
13262
  return __awaiter(this, arguments, void 0, function (collection, db, dbName) {
13125
- var normalized, alias, manager, fallback, candidates, pushCandidate, base, reportCandidate, candidates_4, candidates_4_1, candidate, model, resolved, resolvedName, model, _a, candidates_5, candidates_5_1, candidate;
13126
- var e_30, _b, e_31, _c;
13127
- var _d;
13263
+ var normalized, alias, manager, hasManager, candidates, pushCandidate, base, reportCandidate, candidates_4, candidates_4_1, candidate, model, resolved, resolvedName, resolvedModel, _a, candidates_5, candidates_5_1, candidate, e_30_1, candidates_6, candidates_6_1, candidate;
13264
+ var e_31, _b, e_30, _c, e_32, _d;
13265
+ var _e;
13128
13266
  if (dbName === void 0) { dbName = ''; }
13129
- return __generator(this, function (_e) {
13130
- switch (_e.label) {
13267
+ return __generator(this, function (_f) {
13268
+ switch (_f.label) {
13131
13269
  case 0:
13132
13270
  normalized = normalizeOptionalString(collection);
13133
13271
  if (!normalized) {
13134
13272
  throw new Error('AI assistant report builder bridge: Collection is required.');
13135
13273
  }
13136
13274
  alias = resolveAssistantBridgeCollectionAlias(normalized);
13137
- manager = (_d = resolveio_server_app_1.ResolveIOServer.getMongoManager) === null || _d === void 0 ? void 0 : _d.call(resolveio_server_app_1.ResolveIOServer);
13138
- if (!manager || typeof manager.collection !== 'function') {
13139
- fallback = alias || normalized;
13140
- if (isAssistantDirectCollectionFallbackAllowed(fallback)) {
13141
- return [2 /*return*/, __assign({ collection: fallback }, (fallback !== normalized ? { fallbackFrom: normalized } : {}))];
13142
- }
13143
- throw new Error('AI assistant report builder bridge: Mongo manager unavailable.');
13144
- }
13275
+ manager = (_e = resolveio_server_app_1.ResolveIOServer.getMongoManager) === null || _e === void 0 ? void 0 : _e.call(resolveio_server_app_1.ResolveIOServer);
13276
+ hasManager = !!(manager && typeof manager.collection === 'function');
13145
13277
  candidates = [];
13146
13278
  pushCandidate = function (name) {
13147
13279
  var value = normalizeOptionalString(name);
@@ -13162,64 +13294,99 @@ function resolveAssistantReportBuilderBridgeCollection(collection_1, db_1) {
13162
13294
  if (reportCandidate && reportCandidate !== normalized) {
13163
13295
  pushCandidate(reportCandidate);
13164
13296
  }
13165
- try {
13166
- for (candidates_4 = __values(candidates), candidates_4_1 = candidates_4.next(); !candidates_4_1.done; candidates_4_1 = candidates_4.next()) {
13167
- candidate = candidates_4_1.value;
13168
- model = manager.collection(candidate);
13169
- if (model === null || model === void 0 ? void 0 : model.useRB) {
13170
- return [2 /*return*/, __assign({ collection: candidate }, (candidate !== normalized ? { fallbackFrom: normalized } : {}))];
13297
+ if (hasManager) {
13298
+ try {
13299
+ for (candidates_4 = __values(candidates), candidates_4_1 = candidates_4.next(); !candidates_4_1.done; candidates_4_1 = candidates_4.next()) {
13300
+ candidate = candidates_4_1.value;
13301
+ model = manager.collection(candidate);
13302
+ if (model === null || model === void 0 ? void 0 : model.useRB) {
13303
+ return [2 /*return*/, __assign({ collection: candidate }, (candidate !== normalized ? { fallbackFrom: normalized } : {}))];
13304
+ }
13171
13305
  }
13172
13306
  }
13173
- }
13174
- catch (e_30_1) { e_30 = { error: e_30_1 }; }
13175
- finally {
13176
- try {
13177
- if (candidates_4_1 && !candidates_4_1.done && (_b = candidates_4.return)) _b.call(candidates_4);
13307
+ catch (e_31_1) { e_31 = { error: e_31_1 }; }
13308
+ finally {
13309
+ try {
13310
+ if (candidates_4_1 && !candidates_4_1.done && (_b = candidates_4.return)) _b.call(candidates_4);
13311
+ }
13312
+ finally { if (e_31) throw e_31.error; }
13178
13313
  }
13179
- finally { if (e_30) throw e_30.error; }
13180
13314
  }
13181
13315
  if (!(db && dbName)) return [3 /*break*/, 4];
13182
- _e.label = 1;
13316
+ _f.label = 1;
13183
13317
  case 1:
13184
- _e.trys.push([1, 3, , 4]);
13318
+ _f.trys.push([1, 3, , 4]);
13185
13319
  return [4 /*yield*/, resolveAssistantCollectionName(db, dbName, alias || normalized)];
13186
13320
  case 2:
13187
- resolved = _e.sent();
13321
+ resolved = _f.sent();
13188
13322
  resolvedName = normalizeOptionalString(resolved === null || resolved === void 0 ? void 0 : resolved.name);
13189
13323
  if (resolvedName) {
13190
13324
  pushCandidate(resolvedName);
13191
- model = manager.collection(resolvedName);
13192
- if ((model === null || model === void 0 ? void 0 : model.useRB) || isAssistantDirectCollectionFallbackAllowed(resolvedName)) {
13325
+ resolvedModel = hasManager ? manager.collection(resolvedName) : null;
13326
+ if ((resolvedModel === null || resolvedModel === void 0 ? void 0 : resolvedModel.useRB) || isAssistantDirectCollectionFallbackAllowed(resolvedName)) {
13193
13327
  return [2 /*return*/, __assign({ collection: resolvedName }, (resolvedName !== normalized ? { fallbackFrom: normalized } : {}))];
13194
13328
  }
13195
13329
  }
13196
13330
  return [3 /*break*/, 4];
13197
13331
  case 3:
13198
- _a = _e.sent();
13332
+ _a = _f.sent();
13199
13333
  return [3 /*break*/, 4];
13200
13334
  case 4:
13335
+ if (!db) return [3 /*break*/, 12];
13336
+ _f.label = 5;
13337
+ case 5:
13338
+ _f.trys.push([5, 10, 11, 12]);
13339
+ candidates_5 = __values(candidates), candidates_5_1 = candidates_5.next();
13340
+ _f.label = 6;
13341
+ case 6:
13342
+ if (!!candidates_5_1.done) return [3 /*break*/, 9];
13343
+ candidate = candidates_5_1.value;
13344
+ if (AI_ASSISTANT_BLOCKED_COLLECTIONS.has(candidate)) {
13345
+ return [3 /*break*/, 8];
13346
+ }
13347
+ return [4 /*yield*/, doesAssistantCollectionExistInDb(db, candidate)];
13348
+ case 7:
13349
+ if (_f.sent()) {
13350
+ return [2 /*return*/, __assign({ collection: candidate }, (candidate !== normalized ? { fallbackFrom: normalized } : {}))];
13351
+ }
13352
+ _f.label = 8;
13353
+ case 8:
13354
+ candidates_5_1 = candidates_5.next();
13355
+ return [3 /*break*/, 6];
13356
+ case 9: return [3 /*break*/, 12];
13357
+ case 10:
13358
+ e_30_1 = _f.sent();
13359
+ e_30 = { error: e_30_1 };
13360
+ return [3 /*break*/, 12];
13361
+ case 11:
13201
13362
  try {
13202
- for (candidates_5 = __values(candidates), candidates_5_1 = candidates_5.next(); !candidates_5_1.done; candidates_5_1 = candidates_5.next()) {
13203
- candidate = candidates_5_1.value;
13363
+ if (candidates_5_1 && !candidates_5_1.done && (_c = candidates_5.return)) _c.call(candidates_5);
13364
+ }
13365
+ finally { if (e_30) throw e_30.error; }
13366
+ return [7 /*endfinally*/];
13367
+ case 12:
13368
+ try {
13369
+ for (candidates_6 = __values(candidates), candidates_6_1 = candidates_6.next(); !candidates_6_1.done; candidates_6_1 = candidates_6.next()) {
13370
+ candidate = candidates_6_1.value;
13204
13371
  if (isAssistantDirectCollectionFallbackAllowed(candidate)) {
13205
13372
  return [2 /*return*/, __assign({ collection: candidate }, (candidate !== normalized ? { fallbackFrom: normalized } : {}))];
13206
13373
  }
13207
13374
  }
13208
13375
  }
13209
- catch (e_31_1) { e_31 = { error: e_31_1 }; }
13376
+ catch (e_32_1) { e_32 = { error: e_32_1 }; }
13210
13377
  finally {
13211
13378
  try {
13212
- if (candidates_5_1 && !candidates_5_1.done && (_c = candidates_5.return)) _c.call(candidates_5);
13379
+ if (candidates_6_1 && !candidates_6_1.done && (_d = candidates_6.return)) _d.call(candidates_6);
13213
13380
  }
13214
- finally { if (e_31) throw e_31.error; }
13381
+ finally { if (e_32) throw e_32.error; }
13215
13382
  }
13216
- throw new Error('AI assistant report builder bridge: Collection is not configured for report builder.');
13383
+ throw new Error('AI assistant report builder bridge: No queryable collection could be resolved.');
13217
13384
  }
13218
13385
  });
13219
13386
  });
13220
13387
  }
13221
13388
  function findQueryDateField(query) {
13222
- var e_32, _a, e_33, _b;
13389
+ var e_33, _a, e_34, _b;
13223
13390
  if (!query || typeof query !== 'object') {
13224
13391
  return null;
13225
13392
  }
@@ -13233,12 +13400,12 @@ function findQueryDateField(query) {
13233
13400
  }
13234
13401
  }
13235
13402
  }
13236
- catch (e_32_1) { e_32 = { error: e_32_1 }; }
13403
+ catch (e_33_1) { e_33 = { error: e_33_1 }; }
13237
13404
  finally {
13238
13405
  try {
13239
13406
  if (query_1_1 && !query_1_1.done && (_a = query_1.return)) _a.call(query_1);
13240
13407
  }
13241
- finally { if (e_32) throw e_32.error; }
13408
+ finally { if (e_33) throw e_33.error; }
13242
13409
  }
13243
13410
  return null;
13244
13411
  }
@@ -13257,12 +13424,12 @@ function findQueryDateField(query) {
13257
13424
  }
13258
13425
  }
13259
13426
  }
13260
- catch (e_33_1) { e_33 = { error: e_33_1 }; }
13427
+ catch (e_34_1) { e_34 = { error: e_34_1 }; }
13261
13428
  finally {
13262
13429
  try {
13263
13430
  if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
13264
13431
  }
13265
- finally { if (e_33) throw e_33.error; }
13432
+ finally { if (e_34) throw e_34.error; }
13266
13433
  }
13267
13434
  return null;
13268
13435
  }
@@ -13511,7 +13678,7 @@ function resolveQueryDateFieldFallback(query) {
13511
13678
  return { from: dateField, to: fallback };
13512
13679
  }
13513
13680
  function containsForbiddenMongoOperators(value) {
13514
- var e_34, _a;
13681
+ var e_35, _a;
13515
13682
  if (!value || typeof value !== 'object') {
13516
13683
  return false;
13517
13684
  }
@@ -13530,12 +13697,12 @@ function containsForbiddenMongoOperators(value) {
13530
13697
  }
13531
13698
  }
13532
13699
  }
13533
- catch (e_34_1) { e_34 = { error: e_34_1 }; }
13700
+ catch (e_35_1) { e_35 = { error: e_35_1 }; }
13534
13701
  finally {
13535
13702
  try {
13536
13703
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
13537
13704
  }
13538
- finally { if (e_34) throw e_34.error; }
13705
+ finally { if (e_35) throw e_35.error; }
13539
13706
  }
13540
13707
  return false;
13541
13708
  }
@@ -13858,38 +14025,6 @@ function resolveConfiguredCodexAutoThoughtLevel(kind) {
13858
14025
  || process.env["AI_DASHBOARD_CODEX_".concat(levelKey, "_THOUGHT_LEVEL")]);
13859
14026
  return configured || fallbackLevel;
13860
14027
  }
13861
- function resolveAutoCodexThoughtLevel(params) {
13862
- var combinedText = [
13863
- normalizeOptionalString(params === null || params === void 0 ? void 0 : params.message),
13864
- normalizeOptionalString(params === null || params === void 0 ? void 0 : params.attachmentText)
13865
- ].filter(Boolean).join('\n').toLowerCase();
13866
- var simpleLevel = resolveConfiguredCodexAutoThoughtLevel('simple');
13867
- var complexLevel = resolveConfiguredCodexAutoThoughtLevel('complex');
13868
- if (!combinedText) {
13869
- return simpleLevel;
13870
- }
13871
- var bugOrIssuePatterns = [
13872
- /\bbug\b/i,
13873
- /\bissue\b/i,
13874
- /\berror\b/i,
13875
- /\bexception\b/i,
13876
- /\bfail(?:ed|ing|ure)?\b/i,
13877
- /\bbroken\b/i,
13878
- /\bnot\s+working\b/i,
13879
- /\bdoesn['’]t\s+work\b/i,
13880
- /\bwhy\s+is\s+this\s+happening\b/i,
13881
- /\broot\s+cause\b/i,
13882
- /\bregression\b/i,
13883
- /\bdebug\b/i,
13884
- /\binvestigat(?:e|ion)\b/i,
13885
- /\bfix\b/i,
13886
- /\bcrash(?:ed|ing)?\b/i,
13887
- /\btimeout\b/i,
13888
- /\bwrong\b/i,
13889
- /\bincorrect\b/i
13890
- ];
13891
- return bugOrIssuePatterns.some(function (pattern) { return pattern.test(combinedText); }) ? complexLevel : simpleLevel;
13892
- }
13893
14028
  function resolveCodexThoughtLevel(params) {
13894
14029
  var config = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
13895
14030
  var raw = normalizeOptionalString(config['AI_ASSISTANT_CODEX_THOUGHT_LEVEL']
@@ -13900,13 +14035,17 @@ function resolveCodexThoughtLevel(params) {
13900
14035
  || process.env.AI_DASHBOARD_CODEX_THOUGHT_LEVEL);
13901
14036
  var normalized = (raw || '').trim().toLowerCase();
13902
14037
  var explicitLevel = normalizeCodexThoughtLevel(normalized);
14038
+ var isBugIssueRequest = (params === null || params === void 0 ? void 0 : params.requestType) === 'bug_issue';
14039
+ if (!isBugIssueRequest) {
14040
+ return 'medium';
14041
+ }
13903
14042
  if (explicitLevel) {
13904
14043
  return explicitLevel;
13905
14044
  }
13906
14045
  if (normalized === 'auto' || !normalized) {
13907
- return resolveAutoCodexThoughtLevel(params);
14046
+ return resolveConfiguredCodexAutoThoughtLevel('complex');
13908
14047
  }
13909
- return 'medium';
14048
+ return 'high';
13910
14049
  }
13911
14050
  function resolveCodexSettings(options) {
13912
14051
  var serverConfig = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
@@ -13978,8 +14117,8 @@ function applyCodexStreamStatusHandler(runOptions, streamStatusHandler) {
13978
14117
  }
13979
14118
  function waitForCodexWorkerMessage(worker, streamStatusHandler) {
13980
14119
  return __awaiter(this, void 0, void 0, function () {
13981
- var _a, _b, _c, _d, message, payload, status_1, e_35_1;
13982
- var _e, e_35, _f, _g;
14120
+ var _a, _b, _c, _d, message, payload, status_1, e_36_1;
14121
+ var _e, e_36, _f, _g;
13983
14122
  return __generator(this, function (_h) {
13984
14123
  switch (_h.label) {
13985
14124
  case 0:
@@ -14006,8 +14145,8 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
14006
14145
  return [3 /*break*/, 1];
14007
14146
  case 4: return [3 /*break*/, 11];
14008
14147
  case 5:
14009
- e_35_1 = _h.sent();
14010
- e_35 = { error: e_35_1 };
14148
+ e_36_1 = _h.sent();
14149
+ e_36 = { error: e_36_1 };
14011
14150
  return [3 /*break*/, 11];
14012
14151
  case 6:
14013
14152
  _h.trys.push([6, , 9, 10]);
@@ -14018,7 +14157,7 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
14018
14157
  _h.label = 8;
14019
14158
  case 8: return [3 /*break*/, 10];
14020
14159
  case 9:
14021
- if (e_35) throw e_35.error;
14160
+ if (e_36) throw e_36.error;
14022
14161
  return [7 /*endfinally*/];
14023
14162
  case 10: return [7 /*endfinally*/];
14024
14163
  case 11: throw new CodexWorkerBootstrapError('Codex worker exited before completing.');
@@ -14587,6 +14726,20 @@ function classifyAssistantRequestType(message, plannerOutput) {
14587
14726
  plannerIntentType: plannerIntentRaw || undefined
14588
14727
  };
14589
14728
  }
14729
+ function shouldRunAssistantPlanner(params) {
14730
+ if (!(params === null || params === void 0 ? void 0 : params.plannerEnabled)) {
14731
+ return false;
14732
+ }
14733
+ if (params === null || params === void 0 ? void 0 : params.hasDeterministicHeuristicFastPath) {
14734
+ return false;
14735
+ }
14736
+ var requestClassification = params === null || params === void 0 ? void 0 : params.requestClassification;
14737
+ if (requestClassification === null || requestClassification === void 0 ? void 0 : requestClassification.dataQuestion) {
14738
+ return true;
14739
+ }
14740
+ var type = (requestClassification === null || requestClassification === void 0 ? void 0 : requestClassification.type) || 'unknown';
14741
+ return type === 'unknown' || type === 'mixed';
14742
+ }
14590
14743
  function resolveAssistantRequestedTimeGrain(message, plannerOutput) {
14591
14744
  var _a, _b;
14592
14745
  var plannerGrain = normalizeOptionalString((_b = (_a = plannerOutput === null || plannerOutput === void 0 ? void 0 : plannerOutput.dataPlan) === null || _a === void 0 ? void 0 : _a.timeRange) === null || _b === void 0 ? void 0 : _b.grain).toLowerCase();
@@ -14680,7 +14833,7 @@ var AI_ASSISTANT_BREAKDOWN_DIMENSION_STOPWORDS = new Set([
14680
14833
  'by'
14681
14834
  ]);
14682
14835
  function normalizeAssistantBreakdownDimension(value) {
14683
- var e_36, _a;
14836
+ var e_37, _a;
14684
14837
  var normalized = normalizeOptionalString(value)
14685
14838
  .toLowerCase()
14686
14839
  .replace(/[^a-z0-9_\s-]+/g, ' ')
@@ -14712,12 +14865,12 @@ function normalizeAssistantBreakdownDimension(value) {
14712
14865
  }
14713
14866
  }
14714
14867
  }
14715
- catch (e_36_1) { e_36 = { error: e_36_1 }; }
14868
+ catch (e_37_1) { e_37 = { error: e_37_1 }; }
14716
14869
  finally {
14717
14870
  try {
14718
14871
  if (tokens_1_1 && !tokens_1_1.done && (_a = tokens_1.return)) _a.call(tokens_1);
14719
14872
  }
14720
- finally { if (e_36) throw e_36.error; }
14873
+ finally { if (e_37) throw e_37.error; }
14721
14874
  }
14722
14875
  if (!kept.length) {
14723
14876
  return '';
@@ -14904,7 +15057,7 @@ function resolveAssistantPlannerEnabled() {
14904
15057
  return raw === undefined ? true : raw === true;
14905
15058
  }
14906
15059
  function resolveAssistantPlannerKnownRoutes() {
14907
- var e_37, _a;
15060
+ var e_38, _a;
14908
15061
  var _b;
14909
15062
  var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
14910
15063
  var unique = new Set();
@@ -14917,12 +15070,12 @@ function resolveAssistantPlannerKnownRoutes() {
14917
15070
  }
14918
15071
  }
14919
15072
  }
14920
- catch (e_37_1) { e_37 = { error: e_37_1 }; }
15073
+ catch (e_38_1) { e_38 = { error: e_38_1 }; }
14921
15074
  finally {
14922
15075
  try {
14923
15076
  if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
14924
15077
  }
14925
- finally { if (e_37) throw e_37.error; }
15078
+ finally { if (e_38) throw e_38.error; }
14926
15079
  }
14927
15080
  return Array.from(unique).slice(0, AI_ASSISTANT_PLANNER_MAX_ROUTES);
14928
15081
  }
@@ -15165,7 +15318,7 @@ function normalizeRouteMatchKey(value) {
15165
15318
  return normalizeRouteKey(value).toLowerCase();
15166
15319
  }
15167
15320
  function buildClientRouteIndex() {
15168
- var e_38, _a;
15321
+ var e_39, _a;
15169
15322
  var _b;
15170
15323
  var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
15171
15324
  var set = new Set();
@@ -15184,12 +15337,12 @@ function buildClientRouteIndex() {
15184
15337
  }
15185
15338
  }
15186
15339
  }
15187
- catch (e_38_1) { e_38 = { error: e_38_1 }; }
15340
+ catch (e_39_1) { e_39 = { error: e_39_1 }; }
15188
15341
  finally {
15189
15342
  try {
15190
15343
  if (routes_2_1 && !routes_2_1.done && (_a = routes_2.return)) _a.call(routes_2);
15191
15344
  }
15192
- finally { if (e_38) throw e_38.error; }
15345
+ finally { if (e_39) throw e_39.error; }
15193
15346
  }
15194
15347
  return { set: set, map: map, size: routes.length };
15195
15348
  }
@@ -15559,13 +15712,88 @@ var AI_ASSISTANT_CHANGE_HISTORY_PATTERNS = [
15559
15712
  /\bwhat\s+did\s+(?:the\s+)?last\s+(?:system\s+)?update\s+(?:just\s+)?do\b/i,
15560
15713
  /\blast\s+system\s+update\b[\s\S]{0,40}\bdo\b/i,
15561
15714
  /\bhow\s+long\b.*\bbeen\s+(this|that)\s+way\b/i,
15715
+ /\bhow\s+long\b[\s\S]{0,80}\bbeen\s+around\b/i,
15562
15716
  /\bsince\s+when\b/i,
15717
+ /\bwhen\s+was\b[\s\S]{0,80}\bintroduced\b/i,
15563
15718
  /\bchangelog\b/i,
15564
15719
  /\brelease\s+notes?\b/i,
15565
15720
  /\bgithub\b/i,
15566
15721
  /\bcommits?\b/i,
15567
15722
  /\bupdate\s+history\b/i
15568
15723
  ];
15724
+ var AI_ASSISTANT_CHANGE_HISTORY_TOKEN_STOPWORDS = new Set([
15725
+ 'the',
15726
+ 'a',
15727
+ 'an',
15728
+ 'to',
15729
+ 'for',
15730
+ 'of',
15731
+ 'in',
15732
+ 'on',
15733
+ 'at',
15734
+ 'and',
15735
+ 'or',
15736
+ 'i',
15737
+ 'me',
15738
+ 'my',
15739
+ 'we',
15740
+ 'us',
15741
+ 'you',
15742
+ 'our',
15743
+ 'is',
15744
+ 'are',
15745
+ 'do',
15746
+ 'did',
15747
+ 'does',
15748
+ 'can',
15749
+ 'could',
15750
+ 'would',
15751
+ 'should',
15752
+ 'what',
15753
+ 'when',
15754
+ 'where',
15755
+ 'which',
15756
+ 'why',
15757
+ 'how',
15758
+ 'long',
15759
+ 'has',
15760
+ 'have',
15761
+ 'had',
15762
+ 'been',
15763
+ 'this',
15764
+ 'that',
15765
+ 'these',
15766
+ 'those',
15767
+ 'it',
15768
+ 'new',
15769
+ 'changed',
15770
+ 'change',
15771
+ 'recent',
15772
+ 'recently',
15773
+ 'latest',
15774
+ 'last',
15775
+ 'time',
15776
+ 'updated',
15777
+ 'update',
15778
+ 'updates',
15779
+ 'added',
15780
+ 'around',
15781
+ 'page',
15782
+ 'screen',
15783
+ 'feature',
15784
+ 'features',
15785
+ 'history',
15786
+ 'list',
15787
+ 'dashboard',
15788
+ 'server',
15789
+ 'management',
15790
+ 'system',
15791
+ 'release',
15792
+ 'notes',
15793
+ 'github',
15794
+ 'commits',
15795
+ 'commit'
15796
+ ]);
15569
15797
  function isAssistantChangeHistoryQuestion(message) {
15570
15798
  var text = normalizeOptionalString(message).toLowerCase();
15571
15799
  if (!text) {
@@ -15597,6 +15825,13 @@ function resolveAssistantChangeHistoryLimit(message) {
15597
15825
  }
15598
15826
  return AI_ASSISTANT_CHANGE_HISTORY_DEFAULT_LIMIT;
15599
15827
  }
15828
+ function resolveAssistantChangeHistoryDepth(message, limit) {
15829
+ var normalizedLimit = Math.min(Math.max((0, common_1.round)(limit || 0), 1), AI_ASSISTANT_CHANGE_HISTORY_MAX_LIMIT);
15830
+ if (isAssistantChangeDurationQuestion(message)) {
15831
+ return Math.min(Math.max(normalizedLimit * 40, AI_ASSISTANT_CHANGE_HISTORY_MAX_DEPTH), AI_ASSISTANT_CHANGE_HISTORY_DURATION_MAX_DEPTH);
15832
+ }
15833
+ return Math.min(Math.max(normalizedLimit * 8, AI_ASSISTANT_CHANGE_HISTORY_MIN_DEPTH), AI_ASSISTANT_CHANGE_HISTORY_MAX_DEPTH);
15834
+ }
15600
15835
  function resolveAssistantChangeHistoryFetchEnabled() {
15601
15836
  var config = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
15602
15837
  var normalized = normalizeOptionalBoolean(config['AI_ASSISTANT_GIT_FETCH_ENABLED']
@@ -15612,6 +15847,43 @@ function shouldAssistantFetchGitRemote(message) {
15612
15847
  }
15613
15848
  return /\b(github|latest|newest|up to date|up-to-date|pull|remote)\b/i.test(text);
15614
15849
  }
15850
+ function resolveAssistantChangeHistoryKeywords(message) {
15851
+ var rawTokens = normalizeOptionalString(message)
15852
+ .toLowerCase()
15853
+ .split(/[^a-z0-9]+/g)
15854
+ .map(function (token) { return token.trim(); })
15855
+ .filter(Boolean);
15856
+ var keywords = [];
15857
+ rawTokens.forEach(function (token) {
15858
+ normalizeCollectionToken(token).forEach(function (normalized) {
15859
+ if (!normalized || normalized.length < 4 || AI_ASSISTANT_CHANGE_HISTORY_TOKEN_STOPWORDS.has(normalized)) {
15860
+ return;
15861
+ }
15862
+ keywords.push(normalized);
15863
+ });
15864
+ });
15865
+ return Array.from(new Set(keywords));
15866
+ }
15867
+ function scoreAssistantChangeHistoryCommitByKeywords(commit, keywords) {
15868
+ if (!Array.isArray(keywords) || !keywords.length) {
15869
+ return 0;
15870
+ }
15871
+ var subject = normalizeOptionalString(commit === null || commit === void 0 ? void 0 : commit.subject).toLowerCase();
15872
+ var files = Array.isArray(commit === null || commit === void 0 ? void 0 : commit.files)
15873
+ ? commit.files.map(function (file) { return normalizeOptionalString(file).toLowerCase(); }).filter(Boolean).join(' ')
15874
+ : '';
15875
+ var haystack = "".concat(subject, " ").concat(files).trim();
15876
+ if (!haystack) {
15877
+ return 0;
15878
+ }
15879
+ var score = 0;
15880
+ keywords.forEach(function (keyword) {
15881
+ if (keyword && haystack.includes(keyword)) {
15882
+ score += keyword.length >= 8 ? 2 : 1;
15883
+ }
15884
+ });
15885
+ return score;
15886
+ }
15615
15887
  function resolveAssistantChangeModulesFromText(message) {
15616
15888
  var text = normalizeOptionalString(message).toLowerCase();
15617
15889
  if (!text) {
@@ -15916,9 +16188,22 @@ function buildAssistantChangeHistorySummaryFromCommits(params) {
15916
16188
  }
15917
16189
  return __assign({ response: lines_3.join('\n'), reason: 'generic', commitCount: 0, generic: true }, (branch ? { branch: branch } : {}));
15918
16190
  }
15919
- var themes = summarizeAssistantChangeThemes(permittedCommits);
16191
+ var featureKeywords = resolveAssistantChangeHistoryKeywords(message);
16192
+ var keywordScopedCommits = featureKeywords.length
16193
+ ? permittedCommits
16194
+ .map(function (commit, index) { return ({
16195
+ commit: commit,
16196
+ index: index,
16197
+ score: scoreAssistantChangeHistoryCommitByKeywords(commit, featureKeywords)
16198
+ }); })
16199
+ .filter(function (entry) { return entry.score > 0; })
16200
+ .sort(function (a, b) { return (b.score - a.score) || (a.index - b.index); })
16201
+ .map(function (entry) { return entry.commit; })
16202
+ : [];
16203
+ var relevantCommits = keywordScopedCommits.length ? keywordScopedCommits : permittedCommits;
16204
+ var themes = summarizeAssistantChangeThemes(relevantCommits);
15920
16205
  var limit = resolveAssistantChangeHistoryLimit(message);
15921
- var topCommits = permittedCommits.slice(0, Math.max(limit, 1));
16206
+ var topCommits = relevantCommits.slice(0, Math.max(limit, 1));
15922
16207
  var lines = [title];
15923
16208
  if (themes.length) {
15924
16209
  lines.push("- Themes: ".concat(themes.join(', '), "."));
@@ -15928,7 +16213,10 @@ function buildAssistantChangeHistorySummaryFromCommits(params) {
15928
16213
  lines.push("- ".concat(dateText, ": ").concat(sanitizeAssistantChangeSubject(commit.subject), "."));
15929
16214
  });
15930
16215
  if (asksDuration) {
15931
- var datedCommits = permittedCommits
16216
+ if (featureKeywords.length && !keywordScopedCommits.length) {
16217
+ lines.push('- I could not find exact feature-term matches in recent commits, so this estimate uses the closest available history.');
16218
+ }
16219
+ var datedCommits = relevantCommits
15932
16220
  .map(function (commit) { return ({ commit: commit, date: new Date(commit.date) }); })
15933
16221
  .filter(function (entry) { return !Number.isNaN(entry.date.getTime()); });
15934
16222
  if (datedCommits.length) {
@@ -16017,7 +16305,7 @@ function resolveAssistantChangeHistoryFastPathResponse(params) {
16017
16305
  return [3 /*break*/, 14];
16018
16306
  case 14:
16019
16307
  limit = resolveAssistantChangeHistoryLimit(params.message);
16020
- historyDepth = Math.min(Math.max(limit * 8, 80), 240);
16308
+ historyDepth = resolveAssistantChangeHistoryDepth(params.message, limit);
16021
16309
  return [4 /*yield*/, runAssistantGitCommand(gitRoot, [
16022
16310
  'log',
16023
16311
  '-n',
@@ -16220,7 +16508,7 @@ function sanitizeAssistantResponse(value) {
16220
16508
  return normalizeAssistantRoutes(normalizedCurrency);
16221
16509
  }
16222
16510
  function evaluateAssistantGuardrails(message) {
16223
- var e_39, _a;
16511
+ var e_40, _a;
16224
16512
  var normalized = String(message || '').toLowerCase();
16225
16513
  var patterns = [
16226
16514
  {
@@ -16266,12 +16554,12 @@ function evaluateAssistantGuardrails(message) {
16266
16554
  }
16267
16555
  }
16268
16556
  }
16269
- catch (e_39_1) { e_39 = { error: e_39_1 }; }
16557
+ catch (e_40_1) { e_40 = { error: e_40_1 }; }
16270
16558
  finally {
16271
16559
  try {
16272
16560
  if (patterns_1_1 && !patterns_1_1.done && (_a = patterns_1.return)) _a.call(patterns_1);
16273
16561
  }
16274
- finally { if (e_39) throw e_39.error; }
16562
+ finally { if (e_40) throw e_40.error; }
16275
16563
  }
16276
16564
  return null;
16277
16565
  }
@@ -16386,7 +16674,7 @@ function tokenizeArithmeticExpression(expression) {
16386
16674
  return tokens;
16387
16675
  }
16388
16676
  function evaluateArithmeticExpression(expression) {
16389
- var e_40, _a, e_41, _b;
16677
+ var e_41, _a, e_42, _b;
16390
16678
  var tokens = tokenizeArithmeticExpression(expression);
16391
16679
  if (!tokens || !tokens.length) {
16392
16680
  return null;
@@ -16443,12 +16731,12 @@ function evaluateArithmeticExpression(expression) {
16443
16731
  prevToken = token;
16444
16732
  }
16445
16733
  }
16446
- catch (e_40_1) { e_40 = { error: e_40_1 }; }
16734
+ catch (e_41_1) { e_41 = { error: e_41_1 }; }
16447
16735
  finally {
16448
16736
  try {
16449
16737
  if (tokens_2_1 && !tokens_2_1.done && (_a = tokens_2.return)) _a.call(tokens_2);
16450
16738
  }
16451
- finally { if (e_40) throw e_40.error; }
16739
+ finally { if (e_41) throw e_41.error; }
16452
16740
  }
16453
16741
  while (ops.length) {
16454
16742
  var op = ops.pop();
@@ -16488,12 +16776,12 @@ function evaluateArithmeticExpression(expression) {
16488
16776
  stack.push(Number(token));
16489
16777
  }
16490
16778
  }
16491
- catch (e_41_1) { e_41 = { error: e_41_1 }; }
16779
+ catch (e_42_1) { e_42 = { error: e_42_1 }; }
16492
16780
  finally {
16493
16781
  try {
16494
16782
  if (output_1_1 && !output_1_1.done && (_b = output_1.return)) _b.call(output_1);
16495
16783
  }
16496
- finally { if (e_41) throw e_41.error; }
16784
+ finally { if (e_42) throw e_42.error; }
16497
16785
  }
16498
16786
  if (stack.length !== 1 || Number.isNaN(stack[0])) {
16499
16787
  return null;
@@ -16677,8 +16965,8 @@ function handleCodexUpload(id_conversation, file_name, content_base64, size, con
16677
16965
  }
16678
16966
  function readAttachmentContents(attachments) {
16679
16967
  return __awaiter(this, void 0, void 0, function () {
16680
- var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_42_1;
16681
- var e_42, _b;
16968
+ var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_43_1;
16969
+ var e_43, _b;
16682
16970
  return __generator(this, function (_c) {
16683
16971
  switch (_c.label) {
16684
16972
  case 0:
@@ -16757,14 +17045,14 @@ function readAttachmentContents(attachments) {
16757
17045
  return [3 /*break*/, 2];
16758
17046
  case 10: return [3 /*break*/, 13];
16759
17047
  case 11:
16760
- e_42_1 = _c.sent();
16761
- e_42 = { error: e_42_1 };
17048
+ e_43_1 = _c.sent();
17049
+ e_43 = { error: e_43_1 };
16762
17050
  return [3 /*break*/, 13];
16763
17051
  case 12:
16764
17052
  try {
16765
17053
  if (attachments_1_1 && !attachments_1_1.done && (_b = attachments_1.return)) _b.call(attachments_1);
16766
17054
  }
16767
- finally { if (e_42) throw e_42.error; }
17055
+ finally { if (e_43) throw e_43.error; }
16768
17056
  return [7 /*endfinally*/];
16769
17057
  case 13: return [2 /*return*/, {
16770
17058
  promptText: chunks.length ? "\n\nAttachments:\n".concat(chunks.join('\n\n')) : '',
@@ -16929,7 +17217,7 @@ function updateAssistantMessageWithFallback(messageId, setPayload) {
16929
17217
  _b.label = 1;
16930
17218
  case 1:
16931
17219
  _b.trys.push([1, 3, , 10]);
16932
- return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: messageId }, { $set: setPayload })];
17220
+ return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: messageId }, { $set: setPayload }, undefined, false, false, true)];
16933
17221
  case 2:
16934
17222
  _b.sent();
16935
17223
  return [2 /*return*/];
@@ -16955,7 +17243,7 @@ function updateAssistantMessageWithFallback(messageId, setPayload) {
16955
17243
  case 7: return [4 /*yield*/, (0, promises_1.setTimeout)(15)];
16956
17244
  case 8:
16957
17245
  _b.sent();
16958
- return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: messageId }, { $set: setPayload })];
17246
+ return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: messageId }, { $set: setPayload }, undefined, false, false, true)];
16959
17247
  case 9:
16960
17248
  _b.sent();
16961
17249
  return [3 /*break*/, 10];
@@ -16980,7 +17268,7 @@ function touchConversation(idConversation, timestamp, lastMessageId) {
16980
17268
  _a.label = 1;
16981
17269
  case 1:
16982
17270
  _a.trys.push([1, 3, , 5]);
16983
- return [4 /*yield*/, ai_terminal_conversation_collection_1.AiTerminalConversations.updateOne({ _id: idConversation }, { $set: update })];
17271
+ return [4 /*yield*/, ai_terminal_conversation_collection_1.AiTerminalConversations.updateOne({ _id: idConversation }, { $set: update }, undefined, false, false, true)];
16984
17272
  case 2:
16985
17273
  _a.sent();
16986
17274
  return [2 /*return*/];
@@ -17088,7 +17376,7 @@ function estimateUsage(messages, responseText, model) {
17088
17376
  };
17089
17377
  }
17090
17378
  function evaluateGuardrails(message) {
17091
- var e_43, _a;
17379
+ var e_44, _a;
17092
17380
  var normalized = String(message || '').toLowerCase();
17093
17381
  var patterns = [
17094
17382
  { pattern: /\b(source\s*code|full\s*code|entire\s*code|repo\s*dump|repository|git\s*clone)\b/i, reason: 'Code access is restricted.' },
@@ -17110,12 +17398,12 @@ function evaluateGuardrails(message) {
17110
17398
  }
17111
17399
  }
17112
17400
  }
17113
- catch (e_43_1) { e_43 = { error: e_43_1 }; }
17401
+ catch (e_44_1) { e_44 = { error: e_44_1 }; }
17114
17402
  finally {
17115
17403
  try {
17116
17404
  if (patterns_2_1 && !patterns_2_1.done && (_a = patterns_2.return)) _a.call(patterns_2);
17117
17405
  }
17118
- finally { if (e_43) throw e_43.error; }
17406
+ finally { if (e_44) throw e_44.error; }
17119
17407
  }
17120
17408
  return null;
17121
17409
  }