@resolveio/server-lib 22.1.11 → 22.1.13

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.
@@ -119,6 +119,7 @@ exports.buildDisplayTable = buildDisplayTable;
119
119
  exports.formatDisplayTableMarkdown = formatDisplayTableMarkdown;
120
120
  exports.resolveAssistantReadDisplayMaxRows = resolveAssistantReadDisplayMaxRows;
121
121
  exports.normalizeAssistantNowExprPlaceholders = normalizeAssistantNowExprPlaceholders;
122
+ exports.repairAssistantFieldPathReferenceInPipeline = repairAssistantFieldPathReferenceInPipeline;
122
123
  exports.rewriteMatchExpressionsToExpr = rewriteMatchExpressionsToExpr;
123
124
  exports.normalizeAssistantMonthlyCalendarWindowPipeline = normalizeAssistantMonthlyCalendarWindowPipeline;
124
125
  exports.normalizeAssistantAggregatePipeline = normalizeAssistantAggregatePipeline;
@@ -128,6 +129,7 @@ exports.rewriteEmbeddedMatchObjects = rewriteEmbeddedMatchObjects;
128
129
  exports.resolveAssistantCollectionOverride = resolveAssistantCollectionOverride;
129
130
  exports.resolveAssistantCrossCollectionFallbackCandidates = resolveAssistantCrossCollectionFallbackCandidates;
130
131
  exports.resolveAssistantAvailableCrossCollectionFallbacksFromNames = resolveAssistantAvailableCrossCollectionFallbacksFromNames;
132
+ exports.evaluateAssistantFallbackDocumentsQuality = evaluateAssistantFallbackDocumentsQuality;
131
133
  exports.shouldAcceptAssistantFallbackDocuments = shouldAcceptAssistantFallbackDocuments;
132
134
  exports.collectUserViewPermissions = collectUserViewPermissions;
133
135
  exports.userHasInvoiceAccess = userHasInvoiceAccess;
@@ -255,6 +257,9 @@ var AI_ASSISTANT_CHANGE_HISTORY_MIN_DEPTH = 80;
255
257
  var AI_ASSISTANT_CHANGE_HISTORY_MAX_DEPTH = 240;
256
258
  var AI_ASSISTANT_CHANGE_HISTORY_DURATION_MAX_DEPTH = 1200;
257
259
  var AI_ASSISTANT_GIT_COMMAND_TIMEOUT_MS = 15000;
260
+ var AI_ASSISTANT_GIT_DISCOVERY_MAX_DEPTH = 4;
261
+ var AI_ASSISTANT_GIT_DISCOVERY_MAX_ROOTS = 20;
262
+ var AI_ASSISTANT_GIT_MIRROR_CACHE_TTL_MS = 5 * 60 * 1000;
258
263
  var AI_ASSISTANT_BLOCKED_COLLECTIONS = new Set([
259
264
  'user-groups',
260
265
  'logged-in-users',
@@ -285,6 +290,16 @@ var AI_ASSISTANT_CLIENT_SCOPE_CACHE = new Map();
285
290
  var AI_ASSISTANT_FIELD_INDEX_CACHE = new Map();
286
291
  var AI_ASSISTANT_COLLECTION_CACHE = new Map();
287
292
  var AI_ASSISTANT_COLLECTION_CACHE_TTL_MS = 5 * 60 * 1000;
293
+ var AI_ASSISTANT_COLLECTION_METADATA_CACHE = new Map();
294
+ var AI_ASSISTANT_COLLECTION_METADATA_CACHE_TTL_MS = 10 * 60 * 1000;
295
+ var AI_ASSISTANT_COLLECTION_PROFILE_CACHE = new Map();
296
+ var AI_ASSISTANT_COLLECTION_PROFILE_CACHE_TTL_MS = 10 * 60 * 1000;
297
+ var AI_ASSISTANT_COLLECTION_PROFILE_FIELD_TOKEN_LIMIT = 240;
298
+ var AI_ASSISTANT_SURFACE_INDEX_CACHE_TTL_MS = 10 * 60 * 1000;
299
+ var AI_ASSISTANT_SURFACE_INDEX_MATCH_LIMIT = 8;
300
+ var AI_ASSISTANT_SURFACE_INDEX_COLLECTION_HINT_LIMIT = 6;
301
+ var AI_ASSISTANT_RELATIONSHIP_GRAPH_CACHE = new Map();
302
+ var AI_ASSISTANT_RELATIONSHIP_GRAPH_CACHE_TTL_MS = 10 * 60 * 1000;
288
303
  var AI_ASSISTANT_COLLECTION_STOPWORDS = new Set([
289
304
  'the',
290
305
  'a',
@@ -770,6 +785,8 @@ var AI_ASSISTANT_PLANNER_USER_PROMPT_TEMPLATE = [
770
785
  '',
771
786
  'Collection hints (may be empty): {{collection_hints_json_array}}',
772
787
  'Field hints (may be empty): {{field_hints_json_array}}',
788
+ 'Method hints (may be empty): {{method_hints_json_array}}',
789
+ 'Publication hints (may be empty): {{publication_hints_json_array}}',
773
790
  '',
774
791
  'Important:',
775
792
  '- If invoice-related, permission is satisfied if ANY allowed view contains "invoice" case-insensitive.',
@@ -875,6 +892,8 @@ function drainAssistantCodexRunQueue() {
875
892
  });
876
893
  });
877
894
  }
895
+ var cachedAssistantSurfaceIndex = null;
896
+ var assistantGitMirrorCache = new Map();
878
897
  function loadAiTerminalMethods(methodManager) {
879
898
  var codexWorkerIndex = resolveSingleWorkerTarget(process.env.AI_ASSISTANT_CODEX_WORKER_INDEX
880
899
  || process.env.CODEX_WORKER_INDEX
@@ -1676,7 +1695,7 @@ function executeAiAssistantCodexRun(payload, context) {
1676
1695
  insertResult = _e.sent();
1677
1696
  assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
1678
1697
  enqueueAssistantCodexRun(function () { return __awaiter(_this, void 0, void 0, function () {
1679
- 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;
1698
+ 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, methodHints, publicationHints, collectionTokenization, collectionRanking, collectionSelection, collectionOverride, collectionNames, plannerEnabled, plannerUsed, plannerSkipReason, plannerOutput, plannerRaw, timingBreakdown, codexUsage, accumulateCodexUsage, contextRoute, contextMode, hintSeed, termExpansion, hintText, baseTokens, expandedTokens, baseWeights, expandedWeights, dbName, db, surfaceHints, _a, allowedRoutes, rankedAllowedRoutes, routeHints, rankedCollectionHints, 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;
1680
1699
  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;
1681
1700
  return __generator(this, function (_13) {
1682
1701
  switch (_13.label) {
@@ -1724,6 +1743,8 @@ function executeAiAssistantCodexRun(payload, context) {
1724
1743
  termHints = [];
1725
1744
  collectionHints = [];
1726
1745
  fieldHints = [];
1746
+ methodHints = [];
1747
+ publicationHints = [];
1727
1748
  collectionTokenization = null;
1728
1749
  collectionRanking = null;
1729
1750
  collectionSelection = null;
@@ -1767,7 +1788,7 @@ function executeAiAssistantCodexRun(payload, context) {
1767
1788
  });
1768
1789
  _13.label = 1;
1769
1790
  case 1:
1770
- _13.trys.push([1, 51, 52, 53]);
1791
+ _13.trys.push([1, 52, 53, 54]);
1771
1792
  hintSeed = [message, contextRoute].filter(Boolean).join(' ');
1772
1793
  termExpansion = expandAssistantTermSynonyms(hintSeed);
1773
1794
  hintText = termExpansion.expanded || hintSeed;
@@ -1790,7 +1811,7 @@ function executeAiAssistantCodexRun(payload, context) {
1790
1811
  });
1791
1812
  _13.label = 2;
1792
1813
  case 2:
1793
- _13.trys.push([2, 4, , 5]);
1814
+ _13.trys.push([2, 5, , 6]);
1794
1815
  dbName = resolveAssistantDatabaseName(undefined, input.mongo);
1795
1816
  db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
1796
1817
  return [4 /*yield*/, listAssistantCollections(db, dbName)];
@@ -1798,22 +1819,43 @@ function executeAiAssistantCodexRun(payload, context) {
1798
1819
  collectionNames = _13.sent();
1799
1820
  collectionHints = resolveCollectionHintsFromTokens(expandedTokens, collectionNames, 5);
1800
1821
  collectionRanking = buildCollectionRankingDebugFromTokens(expandedTokens, collectionNames, 8);
1801
- return [3 /*break*/, 5];
1822
+ return [4 /*yield*/, resolveAssistantSurfaceHints(hintSeed, contextRoute, collectionNames)];
1802
1823
  case 4:
1824
+ surfaceHints = _13.sent();
1825
+ methodHints = surfaceHints.methodHints;
1826
+ publicationHints = surfaceHints.publicationHints;
1827
+ if (surfaceHints.collectionHints.length) {
1828
+ collectionHints = mergeAssistantHintValues(surfaceHints.collectionHints, collectionHints);
1829
+ }
1830
+ return [3 /*break*/, 6];
1831
+ case 5:
1803
1832
  _a = _13.sent();
1804
1833
  collectionHints = [];
1805
1834
  collectionRanking = collectionRanking || ((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens)
1806
1835
  ? buildCollectionRankingDebugFromTokens(collectionTokenization.expandedTokens || [], [], 0)
1807
1836
  : null);
1808
- return [3 /*break*/, 5];
1809
- case 5:
1810
- routeHints = resolveCollectionHintsFromRoute(contextRoute, collectionNames);
1837
+ return [3 /*break*/, 6];
1838
+ case 6:
1839
+ allowedRoutes = resolveAssistantAllowedRoutesForUser(user, isSuperAdmin);
1840
+ rankedAllowedRoutes = rankAssistantNavigationRoutes(hintSeed, allowedRoutes, 3);
1841
+ routeHints = mergeAssistantHintValues(resolveCollectionHintsFromRoute(contextRoute, collectionNames), resolveCollectionHintsFromRoutes(rankedAllowedRoutes, collectionNames));
1811
1842
  if (routeHints.length) {
1812
1843
  collectionHints = mergeAssistantHintValues(routeHints, collectionHints);
1813
1844
  }
1814
1845
  if (!collectionHints.length) {
1815
1846
  collectionHints = resolveAssistantDefaultCollectionHints(message);
1816
1847
  }
1848
+ collectionRanking = buildCollectionRankingDebugFromSignals(expandedTokens, collectionNames, {
1849
+ requestedTokens: expandedTokens,
1850
+ methodHints: methodHints,
1851
+ publicationHints: publicationHints,
1852
+ routeHints: mergeAssistantHintValues(contextRoute ? [contextRoute] : [], rankedAllowedRoutes),
1853
+ boostedCollections: collectionHints
1854
+ }, 8);
1855
+ rankedCollectionHints = resolveCollectionHintsFromRanking(collectionRanking, 5);
1856
+ if (rankedCollectionHints.length) {
1857
+ collectionHints = mergeAssistantHintValues(rankedCollectionHints, collectionHints);
1858
+ }
1817
1859
  rankedCollections = Array.isArray(collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked)
1818
1860
  ? collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked.map(function (entry) { return entry.name; })
1819
1861
  : [];
@@ -1825,7 +1867,9 @@ function executeAiAssistantCodexRun(payload, context) {
1825
1867
  contextMode: contextMode || undefined,
1826
1868
  collectionHints: collectionHints.length ? collectionHints : undefined,
1827
1869
  termHints: termHints.length ? termHints : undefined,
1828
- fieldHints: fieldHints.length ? fieldHints : undefined
1870
+ fieldHints: fieldHints.length ? fieldHints : undefined,
1871
+ methodHints: methodHints.length ? methodHints : undefined,
1872
+ publicationHints: publicationHints.length ? publicationHints : undefined
1829
1873
  });
1830
1874
  assistantContext = buildAssistantContext(input, {
1831
1875
  isSuperAdmin: isSuperAdmin,
@@ -1834,6 +1878,8 @@ function executeAiAssistantCodexRun(payload, context) {
1834
1878
  collectionHints: collectionHints,
1835
1879
  termHints: termHints,
1836
1880
  fieldHints: fieldHints,
1881
+ methodHints: methodHints,
1882
+ publicationHints: publicationHints,
1837
1883
  recentToolError: recentToolError
1838
1884
  });
1839
1885
  heuristicDirectivePrecomputed = dataQuestion ? buildAssistantHeuristicDirective(message, collectionHints) : null;
@@ -1849,7 +1895,7 @@ function executeAiAssistantCodexRun(payload, context) {
1849
1895
  }
1850
1896
  prompt_1 = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1851
1897
  return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
1852
- case 6:
1898
+ case 7:
1853
1899
  workspaceRoot = _13.sent();
1854
1900
  codexConfig = resolveCodexSettings({
1855
1901
  model: codexModel,
@@ -1880,37 +1926,39 @@ function executeAiAssistantCodexRun(payload, context) {
1880
1926
  requestClassification: requestClassification,
1881
1927
  hasDeterministicHeuristicFastPath: hasDeterministicHeuristicFastPath
1882
1928
  });
1883
- if (!shouldRunPlanner) return [3 /*break*/, 11];
1929
+ if (!shouldRunPlanner) return [3 /*break*/, 12];
1884
1930
  plannerUsed = true;
1885
1931
  recordStep('Planning: planner prompt');
1886
1932
  plannerPrompt = buildAssistantPlannerPrompt({
1887
1933
  message: message,
1888
1934
  attachmentText: attachmentData.promptText,
1889
1935
  contextRoute: contextRoute,
1890
- knownRoutes: resolveAssistantPlannerKnownRoutes(),
1936
+ knownRoutes: resolveAssistantPlannerKnownRoutes(user, isSuperAdmin),
1891
1937
  user: user,
1892
1938
  collectionHints: collectionHints,
1893
1939
  fieldHints: fieldHints,
1940
+ methodHints: methodHints,
1941
+ publicationHints: publicationHints,
1894
1942
  inputClientId: input.id_client
1895
1943
  });
1896
- _13.label = 7;
1897
- case 7:
1898
- _13.trys.push([7, 9, , 10]);
1944
+ _13.label = 8;
1945
+ case 8:
1946
+ _13.trys.push([8, 10, , 11]);
1899
1947
  plannerStart = Date.now();
1900
1948
  return [4 /*yield*/, runCodexInWorkerThread(plannerPrompt, plannerRunOptions, codexConfig, streamProgress)];
1901
- case 8:
1949
+ case 9:
1902
1950
  plannerRaw = _13.sent();
1903
1951
  accumulateCodexUsage(plannerPrompt, plannerRaw);
1904
1952
  timingBreakdown.plannerMs = Date.now() - plannerStart;
1905
1953
  plannerOutput = parseJsonObject(plannerRaw);
1906
1954
  recordStep('Planning: planner result', { parsed: !!plannerOutput });
1907
- return [3 /*break*/, 10];
1908
- case 9:
1955
+ return [3 /*break*/, 11];
1956
+ case 10:
1909
1957
  _b = _13.sent();
1910
1958
  recordStep('Planning: planner result', { parsed: false });
1911
- return [3 /*break*/, 10];
1912
- case 10: return [3 /*break*/, 12];
1913
- case 11:
1959
+ return [3 /*break*/, 11];
1960
+ case 11: return [3 /*break*/, 13];
1961
+ case 12:
1914
1962
  if (plannerEnabled) {
1915
1963
  if (hasDeterministicHeuristicFastPath) {
1916
1964
  plannerSkipReason = 'heuristic_directive_fast_path';
@@ -1923,8 +1971,8 @@ function executeAiAssistantCodexRun(payload, context) {
1923
1971
  }
1924
1972
  recordStep('Planning: planner skipped', { reason: plannerSkipReason });
1925
1973
  }
1926
- _13.label = 12;
1927
- case 12:
1974
+ _13.label = 13;
1975
+ case 13:
1928
1976
  requestClassification = classifyAssistantRequestType(message, plannerOutput || undefined);
1929
1977
  dataQuestion = requestClassification.dataQuestion;
1930
1978
  requestedTimeGrain = resolveAssistantRequestedTimeGrain(message, plannerOutput || undefined);
@@ -1975,15 +2023,15 @@ function executeAiAssistantCodexRun(payload, context) {
1975
2023
  timeGrain: requestedTimeGrain || undefined
1976
2024
  });
1977
2025
  }
1978
- if (!(dataQuestion && !directive)) return [3 /*break*/, 16];
2026
+ if (!(dataQuestion && !directive)) return [3 /*break*/, 17];
1979
2027
  recordStep('Directive: determine tool', { type: 'data-question' });
1980
2028
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, directiveStyleHint, directivePromptMode);
1981
- _13.label = 13;
1982
- case 13:
1983
- _13.trys.push([13, 15, , 16]);
2029
+ _13.label = 14;
2030
+ case 14:
2031
+ _13.trys.push([14, 16, , 17]);
1984
2032
  directiveStart = Date.now();
1985
2033
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1986
- case 14:
2034
+ case 15:
1987
2035
  directiveText = _13.sent();
1988
2036
  accumulateCodexUsage(directivePrompt, directiveText);
1989
2037
  timingBreakdown.directiveMs = Date.now() - directiveStart;
@@ -2000,19 +2048,19 @@ function executeAiAssistantCodexRun(payload, context) {
2000
2048
  permissionView: normalizeOptionalString((_t = directive.payload) === null || _t === void 0 ? void 0 : _t.permissionView) || undefined
2001
2049
  });
2002
2050
  }
2003
- return [3 /*break*/, 16];
2004
- case 15:
2005
- _c = _13.sent();
2006
- return [3 /*break*/, 16];
2051
+ return [3 /*break*/, 17];
2007
2052
  case 16:
2008
- if (!(!directive && !dataQuestion)) return [3 /*break*/, 20];
2009
- recordStep('Response: draft initial answer', { mode: 'full' });
2010
- _13.label = 17;
2053
+ _c = _13.sent();
2054
+ return [3 /*break*/, 17];
2011
2055
  case 17:
2012
- _13.trys.push([17, 19, , 20]);
2056
+ if (!(!directive && !dataQuestion)) return [3 /*break*/, 21];
2057
+ recordStep('Response: draft initial answer', { mode: 'full' });
2058
+ _13.label = 18;
2059
+ case 18:
2060
+ _13.trys.push([18, 20, , 21]);
2013
2061
  initialStart = Date.now();
2014
2062
  return [4 /*yield*/, runCodexInWorkerThread(prompt_1, runOptions, codexConfig, streamProgress)];
2015
- case 18:
2063
+ case 19:
2016
2064
  responseText = _13.sent();
2017
2065
  accumulateCodexUsage(prompt_1, responseText);
2018
2066
  timingBreakdown.initialResponseMs = Date.now() - initialStart;
@@ -2029,23 +2077,23 @@ function executeAiAssistantCodexRun(payload, context) {
2029
2077
  permissionView: normalizeOptionalString((_w = directive.payload) === null || _w === void 0 ? void 0 : _w.permissionView) || undefined
2030
2078
  });
2031
2079
  }
2032
- return [3 /*break*/, 20];
2033
- case 19:
2080
+ return [3 /*break*/, 21];
2081
+ case 20:
2034
2082
  error_2 = _13.sent();
2035
2083
  recordStep('Response: initial draft failed', {
2036
2084
  message: normalizeOptionalString(error_2 === null || error_2 === void 0 ? void 0 : error_2.message) || 'Unknown error'
2037
2085
  });
2038
- return [3 /*break*/, 20];
2039
- case 20:
2040
- if (!(!directive && dataQuestion)) return [3 /*break*/, 24];
2086
+ return [3 /*break*/, 21];
2087
+ case 21:
2088
+ if (!(!directive && dataQuestion)) return [3 /*break*/, 25];
2041
2089
  recordStep('Directive: forced retry', { mode: 'directive-only' });
2042
2090
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, directiveStyleHint, directivePromptMode);
2043
- _13.label = 21;
2044
- case 21:
2045
- _13.trys.push([21, 23, , 24]);
2091
+ _13.label = 22;
2092
+ case 22:
2093
+ _13.trys.push([22, 24, , 25]);
2046
2094
  forcedStart = Date.now();
2047
2095
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
2048
- case 22:
2096
+ case 23:
2049
2097
  directiveText = _13.sent();
2050
2098
  accumulateCodexUsage(directivePrompt, directiveText);
2051
2099
  timingBreakdown.forcedDirectiveMs = Date.now() - forcedStart;
@@ -2062,15 +2110,15 @@ function executeAiAssistantCodexRun(payload, context) {
2062
2110
  permissionView: normalizeOptionalString((_z = directive.payload) === null || _z === void 0 ? void 0 : _z.permissionView) || undefined
2063
2111
  });
2064
2112
  }
2065
- return [3 /*break*/, 24];
2066
- case 23:
2067
- _d = _13.sent();
2068
- return [3 /*break*/, 24];
2113
+ return [3 /*break*/, 25];
2069
2114
  case 24:
2115
+ _d = _13.sent();
2116
+ return [3 /*break*/, 25];
2117
+ case 25:
2070
2118
  if (!(directive
2071
2119
  && enforceDatedDirective
2072
2120
  && !isAssistantDeterministicHeuristicDirective(directive)
2073
- && !isAssistantDirectiveDated(directive))) return [3 /*break*/, 28];
2121
+ && !isAssistantDirectiveDated(directive))) return [3 /*break*/, 29];
2074
2122
  recordStep('Directive: dated retry', {
2075
2123
  currentType: directive.type,
2076
2124
  timeGrain: requestedTimeGrain || undefined
@@ -2082,12 +2130,12 @@ function executeAiAssistantCodexRun(payload, context) {
2082
2130
  requestedBreakdowns: requestedBreakdownDimensions,
2083
2131
  strict: true
2084
2132
  }), 'aggregate_only');
2085
- _13.label = 25;
2086
- case 25:
2087
- _13.trys.push([25, 27, , 28]);
2133
+ _13.label = 26;
2134
+ case 26:
2135
+ _13.trys.push([26, 28, , 29]);
2088
2136
  strictStart = Date.now();
2089
2137
  return [4 /*yield*/, runCodexInWorkerThread(strictDirectivePrompt, runOptions, codexConfig, streamProgress)];
2090
- case 26:
2138
+ case 27:
2091
2139
  strictDirectiveText = _13.sent();
2092
2140
  accumulateCodexUsage(strictDirectivePrompt, strictDirectiveText);
2093
2141
  timingBreakdown.forcedDirectiveMs += Date.now() - strictStart;
@@ -2109,15 +2157,15 @@ function executeAiAssistantCodexRun(payload, context) {
2109
2157
  timeGrain: requestedTimeGrain || undefined
2110
2158
  });
2111
2159
  }
2112
- return [3 /*break*/, 28];
2113
- case 27:
2114
- _e = _13.sent();
2115
- return [3 /*break*/, 28];
2160
+ return [3 /*break*/, 29];
2116
2161
  case 28:
2162
+ _e = _13.sent();
2163
+ return [3 /*break*/, 29];
2164
+ case 29:
2117
2165
  if (!(directive
2118
2166
  && enforceDatedDirective
2119
2167
  && !isAssistantDeterministicHeuristicDirective(directive)
2120
- && directive.type === 'read')) return [3 /*break*/, 32];
2168
+ && directive.type === 'read')) return [3 /*break*/, 33];
2121
2169
  recordStep('Directive: dated guard retry', {
2122
2170
  currentType: directive.type,
2123
2171
  timeGrain: requestedTimeGrain || undefined
@@ -2129,12 +2177,12 @@ function executeAiAssistantCodexRun(payload, context) {
2129
2177
  requestedBreakdowns: requestedBreakdownDimensions,
2130
2178
  strict: true
2131
2179
  }), 'aggregate_only');
2132
- _13.label = 29;
2133
- case 29:
2134
- _13.trys.push([29, 31, , 32]);
2180
+ _13.label = 30;
2181
+ case 30:
2182
+ _13.trys.push([30, 32, , 33]);
2135
2183
  guardStart = Date.now();
2136
2184
  return [4 /*yield*/, runCodexInWorkerThread(guardDirectivePrompt, runOptions, codexConfig, streamProgress)];
2137
- case 30:
2185
+ case 31:
2138
2186
  guardDirectiveText = _13.sent();
2139
2187
  accumulateCodexUsage(guardDirectivePrompt, guardDirectiveText);
2140
2188
  timingBreakdown.forcedDirectiveMs += Date.now() - guardStart;
@@ -2154,15 +2202,15 @@ function executeAiAssistantCodexRun(payload, context) {
2154
2202
  timeGrain: requestedTimeGrain || undefined
2155
2203
  });
2156
2204
  }
2157
- return [3 /*break*/, 32];
2158
- case 31:
2159
- _f = _13.sent();
2160
- return [3 /*break*/, 32];
2205
+ return [3 /*break*/, 33];
2161
2206
  case 32:
2207
+ _f = _13.sent();
2208
+ return [3 /*break*/, 33];
2209
+ case 33:
2162
2210
  if (!(directive
2163
2211
  && enforceGroupedDirective
2164
2212
  && !isAssistantDeterministicHeuristicDirective(directive)
2165
- && !isAssistantDirectiveGrouped(directive))) return [3 /*break*/, 36];
2213
+ && !isAssistantDirectiveGrouped(directive))) return [3 /*break*/, 37];
2166
2214
  recordStep('Directive: grouped guard retry', {
2167
2215
  currentType: directive.type,
2168
2216
  breakdownDimensions: requestedBreakdownDimensions.length ? requestedBreakdownDimensions : undefined
@@ -2174,12 +2222,12 @@ function executeAiAssistantCodexRun(payload, context) {
2174
2222
  requestedBreakdowns: requestedBreakdownDimensions,
2175
2223
  strict: true
2176
2224
  }), 'aggregate_only');
2177
- _13.label = 33;
2178
- case 33:
2179
- _13.trys.push([33, 35, , 36]);
2225
+ _13.label = 34;
2226
+ case 34:
2227
+ _13.trys.push([34, 36, , 37]);
2180
2228
  groupedStart = Date.now();
2181
2229
  return [4 /*yield*/, runCodexInWorkerThread(groupedDirectivePrompt, runOptions, codexConfig, streamProgress)];
2182
- case 34:
2230
+ case 35:
2183
2231
  groupedDirectiveText = _13.sent();
2184
2232
  accumulateCodexUsage(groupedDirectivePrompt, groupedDirectiveText);
2185
2233
  timingBreakdown.forcedDirectiveMs += Date.now() - groupedStart;
@@ -2202,11 +2250,11 @@ function executeAiAssistantCodexRun(payload, context) {
2202
2250
  timeGrain: requestedTimeGrain || undefined
2203
2251
  });
2204
2252
  }
2205
- return [3 /*break*/, 36];
2206
- case 35:
2207
- _g = _13.sent();
2208
- return [3 /*break*/, 36];
2253
+ return [3 /*break*/, 37];
2209
2254
  case 36:
2255
+ _g = _13.sent();
2256
+ return [3 /*break*/, 37];
2257
+ case 37:
2210
2258
  if (!directive && dataQuestion) {
2211
2259
  heuristicDirective = buildAssistantHeuristicDirective(message, collectionHints);
2212
2260
  if (isAssistantExecutableDirective(heuristicDirective)) {
@@ -2245,7 +2293,7 @@ function executeAiAssistantCodexRun(payload, context) {
2245
2293
  if (cleanedResponseText) {
2246
2294
  assistantContent = sanitizeAssistantResponse(cleanedResponseText);
2247
2295
  }
2248
- if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 49];
2296
+ if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 50];
2249
2297
  effectiveDirective = collectionOverride
2250
2298
  ? __assign(__assign({}, directive), { payload: __assign(__assign({}, (directive.payload || {})), { collection: collectionOverride.to }) }) : directive;
2251
2299
  toolRequest = buildAssistantToolRequest(effectiveDirective, input);
@@ -2255,20 +2303,20 @@ function executeAiAssistantCodexRun(payload, context) {
2255
2303
  collection: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.collection) || undefined,
2256
2304
  permissionView: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.permissionView) || undefined
2257
2305
  });
2258
- _13.label = 37;
2259
- case 37:
2260
- _13.trys.push([37, 47, , 48]);
2306
+ _13.label = 38;
2307
+ case 38:
2308
+ _13.trys.push([38, 48, , 49]);
2261
2309
  toolStart = Date.now();
2262
- if (!(effectiveDirective.type === 'aggregate')) return [3 /*break*/, 39];
2310
+ if (!(effectiveDirective.type === 'aggregate')) return [3 /*break*/, 40];
2263
2311
  return [4 /*yield*/, executeAiAssistantReportBuilderAggregate(toolRequest, context)];
2264
- case 38:
2312
+ case 39:
2265
2313
  _h = _13.sent();
2266
- return [3 /*break*/, 41];
2267
- case 39: return [4 /*yield*/, executeAiAssistantReportBuilderRead(toolRequest, context)];
2268
- case 40:
2269
- _h = _13.sent();
2270
- _13.label = 41;
2314
+ return [3 /*break*/, 42];
2315
+ case 40: return [4 /*yield*/, executeAiAssistantReportBuilderRead(toolRequest, context)];
2271
2316
  case 41:
2317
+ _h = _13.sent();
2318
+ _13.label = 42;
2319
+ case 42:
2272
2320
  toolResponse = _h;
2273
2321
  timingBreakdown.toolMs = Date.now() - toolStart;
2274
2322
  toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
@@ -2284,54 +2332,54 @@ function executeAiAssistantCodexRun(payload, context) {
2284
2332
  progressTracker.push('Drafting response');
2285
2333
  skipFollowupCodex = usedDeterministicHeuristicFastPath
2286
2334
  || isAssistantDeterministicHeuristicDirective(effectiveDirective);
2287
- if (!skipFollowupCodex) return [3 /*break*/, 42];
2335
+ if (!skipFollowupCodex) return [3 /*break*/, 43];
2288
2336
  recordStep('Drafting response: deterministic summary', {
2289
2337
  reason: normalizeOptionalString(effectiveDirective.rawLine) || 'deterministic_heuristic'
2290
2338
  });
2291
2339
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
2292
2340
  assistantContent = applyAssistantDisplayTableToResponse(assistantContent, toolPayload.result.output.display);
2293
- return [3 /*break*/, 46];
2294
- case 42:
2341
+ return [3 /*break*/, 47];
2342
+ case 43:
2295
2343
  recordStep('Drafting response');
2296
2344
  followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
2297
- _13.label = 43;
2298
- case 43:
2299
- _13.trys.push([43, 45, , 46]);
2345
+ _13.label = 44;
2346
+ case 44:
2347
+ _13.trys.push([44, 46, , 47]);
2300
2348
  followupStart = Date.now();
2301
2349
  return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
2302
- case 44:
2350
+ case 45:
2303
2351
  followupText = _13.sent();
2304
2352
  accumulateCodexUsage(followupPrompt, followupText);
2305
2353
  timingBreakdown.followupMs = Date.now() - followupStart;
2306
2354
  assistantContent = sanitizeAssistantResponse(followupText);
2307
2355
  assistantContent = applyAssistantDisplayTableToResponse(assistantContent, toolPayload.result.output.display);
2308
- return [3 /*break*/, 46];
2309
- case 45:
2356
+ return [3 /*break*/, 47];
2357
+ case 46:
2310
2358
  _j = _13.sent();
2311
2359
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
2312
2360
  assistantContent = applyAssistantDisplayTableToResponse(assistantContent, toolPayload.result.output.display);
2313
- return [3 /*break*/, 46];
2314
- case 46: return [3 /*break*/, 48];
2315
- case 47:
2361
+ return [3 /*break*/, 47];
2362
+ case 47: return [3 /*break*/, 49];
2363
+ case 48:
2316
2364
  error_3 = _13.sent();
2317
2365
  assistantContent = buildAssistantToolErrorMessage(error_3);
2318
2366
  toolError = error_3;
2319
- return [3 /*break*/, 48];
2320
- case 48: return [3 /*break*/, 50];
2321
- case 49:
2367
+ return [3 /*break*/, 49];
2368
+ case 49: return [3 /*break*/, 51];
2369
+ case 50:
2322
2370
  progressTracker.push('Drafting response');
2323
2371
  recordStep('Drafting response');
2324
- _13.label = 50;
2325
- case 50: return [3 /*break*/, 53];
2326
- case 51:
2372
+ _13.label = 51;
2373
+ case 51: return [3 /*break*/, 54];
2374
+ case 52:
2327
2375
  error_4 = _13.sent();
2328
2376
  assistantContent = buildAssistantCodexErrorMessage(error_4);
2329
2377
  recordStep('Error', { message: normalizeOptionalString(error_4 === null || error_4 === void 0 ? void 0 : error_4.message) || 'Unknown error' });
2330
- return [3 /*break*/, 53];
2331
- case 52:
2378
+ return [3 /*break*/, 54];
2379
+ case 53:
2332
2380
  progressTracker.stop();
2333
2381
  return [7 /*endfinally*/];
2334
- case 53:
2382
+ case 54:
2335
2383
  if (!assistantContent) {
2336
2384
  assistantContent = buildAssistantCodexErrorMessage(null);
2337
2385
  }
@@ -2388,6 +2436,8 @@ function executeAiAssistantCodexRun(payload, context) {
2388
2436
  termHints: termHints.length ? termHints : undefined,
2389
2437
  collectionHints: collectionHints.length ? collectionHints : undefined,
2390
2438
  fieldHints: fieldHints.length ? fieldHints : undefined,
2439
+ methodHints: methodHints.length ? methodHints : undefined,
2440
+ publicationHints: publicationHints.length ? publicationHints : undefined,
2391
2441
  collectionTokenization: collectionTokenization || undefined,
2392
2442
  collectionRanking: collectionRanking || undefined,
2393
2443
  collectionSelection: collectionSelection || undefined,
@@ -2427,14 +2477,14 @@ function executeAiAssistantCodexRun(payload, context) {
2427
2477
  output_tokens: codexUsage.output_tokens,
2428
2478
  total_tokens: codexUsage.total_tokens
2429
2479
  } : null;
2430
- if (!finalUsage) return [3 /*break*/, 58];
2480
+ if (!finalUsage) return [3 /*break*/, 59];
2431
2481
  return [4 /*yield*/, resolveClientId(conversation, input.id_client, context === null || context === void 0 ? void 0 : context.id_user)];
2432
- case 54:
2433
- usageClientId = _13.sent();
2434
- if (!usageClientId) return [3 /*break*/, 58];
2435
- _13.label = 55;
2436
2482
  case 55:
2437
- _13.trys.push([55, 57, , 58]);
2483
+ usageClientId = _13.sent();
2484
+ if (!usageClientId) return [3 /*break*/, 59];
2485
+ _13.label = 56;
2486
+ case 56:
2487
+ _13.trys.push([56, 58, , 59]);
2438
2488
  return [4 /*yield*/, (0, openai_usage_ledger_manager_1.recordOpenAIUsage)({
2439
2489
  id_client: usageClientId,
2440
2490
  model: finalUsage.model,
@@ -2445,16 +2495,16 @@ function executeAiAssistantCodexRun(payload, context) {
2445
2495
  id_request: requestId || undefined,
2446
2496
  id_conversation: conversation._id
2447
2497
  })];
2448
- case 56:
2449
- _13.sent();
2450
- return [3 /*break*/, 58];
2451
2498
  case 57:
2499
+ _13.sent();
2500
+ return [3 /*break*/, 59];
2501
+ case 58:
2452
2502
  usageError_1 = _13.sent();
2453
2503
  console.error(new Date(), 'Failed to record codex usage', usageError_1);
2454
- return [3 /*break*/, 58];
2455
- case 58:
2504
+ return [3 /*break*/, 59];
2505
+ case 59:
2456
2506
  finalAssistantDoc = __assign(__assign(__assign(__assign({}, assistantDoc), { _id: assistantMessageId, content: assistantContent, metadata: finalMetadata }), (finalUsage ? { usage: finalUsage } : {})), { updatedAt: finalNow });
2457
- if (!assistantMessageId) return [3 /*break*/, 60];
2507
+ if (!assistantMessageId) return [3 /*break*/, 61];
2458
2508
  setPayload = {
2459
2509
  content: assistantContent,
2460
2510
  metadata: finalMetadata,
@@ -2464,18 +2514,18 @@ function executeAiAssistantCodexRun(payload, context) {
2464
2514
  setPayload.usage = finalUsage;
2465
2515
  }
2466
2516
  return [4 /*yield*/, updateAssistantMessageWithFallback(assistantMessageId, setPayload)];
2467
- case 59:
2517
+ case 60:
2468
2518
  _13.sent();
2469
- _13.label = 60;
2470
- case 60: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
2471
- case 61:
2519
+ _13.label = 61;
2520
+ case 61: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
2521
+ case 62:
2472
2522
  _13.sent();
2473
- if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 63];
2523
+ if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 64];
2474
2524
  return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
2475
- case 62:
2525
+ case 63:
2476
2526
  _13.sent();
2477
- _13.label = 63;
2478
- case 63: return [2 /*return*/, finalAssistantDoc];
2527
+ _13.label = 64;
2528
+ case 64: return [2 /*return*/, finalAssistantDoc];
2479
2529
  }
2480
2530
  });
2481
2531
  }); });
@@ -3003,7 +3053,9 @@ function executeAiAssistantMongoRead(payload, context) {
3003
3053
  case 34:
3004
3054
  hasActiveStatusFilters = collectAssistantActiveMatchFields(executedQuery).length > 0;
3005
3055
  if (!(!documents.length && crossCollectionRetryEnabled && !hasActiveStatusFilters)) return [3 /*break*/, 44];
3006
- return [4 /*yield*/, resolveAssistantAvailableCrossCollectionFallbacks(db, dbName, collection, triedCollections)];
3056
+ return [4 /*yield*/, resolveAssistantAvailableCrossCollectionFallbacks(db, dbName, collection, triedCollections, {
3057
+ fieldHints: extractQueryFieldPaths(executedQuery || {})
3058
+ })];
3007
3059
  case 35:
3008
3060
  crossCollectionCandidates = _s.sent();
3009
3061
  if (!crossCollectionCandidates.length) return [3 /*break*/, 43];
@@ -3277,7 +3329,7 @@ function executeAiAssistantMongoRead(payload, context) {
3277
3329
  }
3278
3330
  function executeAiAssistantMongoAggregate(payload, context) {
3279
3331
  return __awaiter(this, void 0, void 0, function () {
3280
- var input, rawCollection, retryState, triedCollections, crossCollectionRetryEnabled, dbName, db, collectionResolution, collection, bridgeCollection, retryRootCollection, schemaFields, effectivePermissionView, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, sanitizedPipeline, strippedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, executedPipeline, dateField, aggregateOptions, runAggregateWithRepair, initialAggregate, documents, probeDocs, fallback, fallbackPipeline, fallbackAggregate, fallbackDocs, createdFallback, createdPipeline, createdAggregate, createdDocs, expanded, expandedAggregate, expandedDocs, completionFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, completionExprFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, unwindFallback, shouldUnwind, _c, _d, fallbackPipeline, fallbackAggregate, fallbackDocs, nameFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, _e, _loop_1, i, state_1, matchFields_1, _f, aliases, rewrittenPipeline, fallbackAggregate, fallbackDocs, _loop_2, i, state_2, nestedFallbacks, nestedFallbacks_1, nestedFallbacks_1_1, nestedFallback, fallbackPayload, fallbackResult, existingFallbacks, error_6, errorMessage, existingErrors, e_2_1, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, crossCollectionCandidates, crossCollectionCandidates_2, crossCollectionCandidates_2_1, candidateCollection, fallbackPayload, fallbackResult, fallbackDocs, existingFallbacks, rejectedQuality, e_3_1, matchStages, diagnostics, combinedMatch, nameFields, dateFields, queryNoName, _g, queryNoDate, _h, _j, _k, _l, allCollections, base, alt, altCount, _m, verification, sanitizedDocuments, includeIds, displayDocs, idLookupDisplay, display;
3332
+ var input, rawCollection, retryState, triedCollections, crossCollectionRetryEnabled, dbName, db, collectionResolution, collection, bridgeCollection, retryRootCollection, schemaFields, effectivePermissionView, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, sanitizedPipeline, strippedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, executedPipeline, dateField, aggregateOptions, runAggregateWithRepair, initialAggregate, documents, probeDocs, fallback, fallbackPipeline, fallbackAggregate, fallbackDocs, createdFallback, createdPipeline, createdAggregate, createdDocs, expanded, expandedAggregate, expandedDocs, completionFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, completionExprFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, unwindFallback, shouldUnwind, _c, _d, fallbackPipeline, fallbackAggregate, fallbackDocs, nameFallback, fallbackPipeline, fallbackAggregate, fallbackDocs, _e, _loop_1, i, state_1, matchFields_1, _f, aliases, rewrittenPipeline, fallbackAggregate, fallbackDocs, _loop_2, i, state_2, nestedFallbacks, nestedFallbacks_1, nestedFallbacks_1_1, nestedFallback, fallbackPayload, fallbackResult, existingFallbacks, error_6, errorMessage, existingErrors, e_2_1, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, fallbackAcceptanceOptions, crossCollectionCandidates, crossCollectionCandidates_2, crossCollectionCandidates_2_1, candidateCollection, fallbackPayload, fallbackResult, fallbackDocs, fallbackQuality, existingFallbacks, rejectedQuality, e_3_1, matchStages, diagnostics, combinedMatch, nameFields, dateFields, queryNoName, _g, queryNoDate, _h, _j, _k, _l, allCollections, base, alt, altCount, _m, verification, sanitizedDocuments, includeIds, displayDocs, idLookupDisplay, display;
3281
3333
  var e_2, _o, e_3, _p;
3282
3334
  var _this = this;
3283
3335
  var _q, _r;
@@ -3367,7 +3419,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
3367
3419
  ? applyClientScopeFilter(baseQuery, normalizedClient, isSuperAdmin)
3368
3420
  : baseQuery;
3369
3421
  scopedQuery = applyCustomerScopeFilter(clientScopedQuery, collection, customerId, isSuperAdmin);
3370
- normalizedPipeline = normalizeAssistantAggregatePipeline(input.pipeline, collection);
3422
+ normalizedPipeline = normalizeAssistantAggregatePipeline(input.pipeline, collection, input.__assistantMessage);
3371
3423
  sanitizedPipeline = normalizedPipeline;
3372
3424
  if (!isSuperAdmin && customerId) {
3373
3425
  strippedPipeline = stripScopedFieldsFromPipelineWithMeta(normalizedPipeline, ['id_customer', 'other.id_customer']);
@@ -3388,7 +3440,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
3388
3440
  }
3389
3441
  aggregateOptions = __assign(__assign({}, normalizedOptions.aggregateOptions), { readPreference: AI_ASSISTANT_READ_PREFERENCE });
3390
3442
  runAggregateWithRepair = function (pipeline, stage) { return __awaiter(_this, void 0, void 0, function () {
3391
- var docs, error_7, isDateRepair, isRankSortByRepair, isDottedOutputFieldRepair, repaired, docs;
3443
+ var docs, error_7, isDateRepair, isRankSortByRepair, isDottedOutputFieldRepair, repaired, dottedFieldPath, dottedFieldReferenceRepairUsed, pathReferenceRepair, docs;
3392
3444
  return __generator(this, function (_a) {
3393
3445
  switch (_a.label) {
3394
3446
  case 0:
@@ -3412,6 +3464,21 @@ function executeAiAssistantMongoAggregate(payload, context) {
3412
3464
  : isRankSortByRepair
3413
3465
  ? repairAssistantRankSortByInPipeline(pipeline)
3414
3466
  : repairAssistantDottedOutputFieldNamesInPipeline(pipeline);
3467
+ dottedFieldPath = null;
3468
+ dottedFieldReferenceRepairUsed = false;
3469
+ if (isDottedOutputFieldRepair) {
3470
+ dottedFieldPath = extractAssistantDottedFieldPathFromError(error_7);
3471
+ if (dottedFieldPath) {
3472
+ pathReferenceRepair = repairAssistantFieldPathReferenceInPipeline(repaired.pipeline, dottedFieldPath);
3473
+ if (pathReferenceRepair.changed) {
3474
+ dottedFieldReferenceRepairUsed = true;
3475
+ repaired = {
3476
+ pipeline: pathReferenceRepair.pipeline,
3477
+ changed: repaired.changed || pathReferenceRepair.changed
3478
+ };
3479
+ }
3480
+ }
3481
+ }
3415
3482
  if (!repaired.changed || containsForbiddenMongoOperators(repaired.pipeline)) {
3416
3483
  throw error_7;
3417
3484
  }
@@ -3441,7 +3508,10 @@ function executeAiAssistantMongoAggregate(payload, context) {
3441
3508
  attempted: true,
3442
3509
  used: true,
3443
3510
  stage: stage,
3444
- reason: 'normalized_dotted_output_field_names'
3511
+ reason: dottedFieldReferenceRepairUsed
3512
+ ? 'normalized_dotted_output_field_names_and_field_path_references'
3513
+ : 'normalized_dotted_output_field_names',
3514
+ fieldPath: dottedFieldPath || undefined
3445
3515
  };
3446
3516
  }
3447
3517
  return [2 /*return*/, { documents: docs, pipeline: repaired.pipeline }];
@@ -3935,7 +4005,10 @@ function executeAiAssistantMongoAggregate(payload, context) {
3935
4005
  _s.label = 56;
3936
4006
  case 56:
3937
4007
  if (!(!documents.length && crossCollectionRetryEnabled)) return [3 /*break*/, 65];
3938
- return [4 /*yield*/, resolveAssistantAvailableCrossCollectionFallbacks(db, dbName, collection, triedCollections)];
4008
+ fallbackAcceptanceOptions = buildAssistantAggregateFallbackAcceptanceOptions(executedPipeline || []);
4009
+ return [4 /*yield*/, resolveAssistantAvailableCrossCollectionFallbacks(db, dbName, collection, triedCollections, {
4010
+ fieldHints: collectAggregateReferencedFieldPaths(executedPipeline || [])
4011
+ })];
3939
4012
  case 57:
3940
4013
  crossCollectionCandidates = _s.sent();
3941
4014
  if (!crossCollectionCandidates.length) return [3 /*break*/, 65];
@@ -3963,7 +4036,8 @@ function executeAiAssistantMongoAggregate(payload, context) {
3963
4036
  case 60:
3964
4037
  fallbackResult = _s.sent();
3965
4038
  fallbackDocs = Array.isArray(fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.documents) ? fallbackResult.documents : [];
3966
- if (fallbackDocs.length && shouldAcceptAssistantFallbackDocuments(fallbackDocs)) {
4039
+ fallbackQuality = evaluateAssistantFallbackDocumentsQuality(fallbackDocs, fallbackAcceptanceOptions);
4040
+ if (fallbackDocs.length && fallbackQuality.accepted) {
3967
4041
  if (isSuperAdmin && (fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.debug) && typeof fallbackResult.debug === 'object') {
3968
4042
  existingFallbacks = fallbackResult.debug.fallbacks && typeof fallbackResult.debug.fallbacks === 'object'
3969
4043
  ? fallbackResult.debug.fallbacks
@@ -3984,7 +4058,12 @@ function executeAiAssistantMongoAggregate(payload, context) {
3984
4058
  : [];
3985
4059
  rejectedQuality.push({
3986
4060
  collection: candidateCollection,
3987
- reason: 'empty_dimension_values'
4061
+ reason: 'sparse_dimension_values',
4062
+ rowCount: fallbackQuality.rowCount,
4063
+ dimensionFields: fallbackQuality.dimensionFields,
4064
+ bestField: fallbackQuality.bestField,
4065
+ bestFillRate: (0, common_1.round)(fallbackQuality.bestFillRate * 100, 2),
4066
+ averageFillRate: (0, common_1.round)(fallbackQuality.averageFillRate * 100, 2)
3988
4067
  });
3989
4068
  fallbackMeta.collectionRetry.rejectedQuality = rejectedQuality;
3990
4069
  }
@@ -4798,6 +4877,12 @@ function buildAssistantToolRequest(directive, payload) {
4798
4877
  if (!request.mongo && (payload === null || payload === void 0 ? void 0 : payload.mongo)) {
4799
4878
  request.mongo = payload.mongo;
4800
4879
  }
4880
+ if (directive.type === 'aggregate' && !request.__assistantMessage) {
4881
+ var message = normalizeOptionalString(payload === null || payload === void 0 ? void 0 : payload.message);
4882
+ if (message) {
4883
+ request.__assistantMessage = message;
4884
+ }
4885
+ }
4801
4886
  return request;
4802
4887
  }
4803
4888
  function buildAssistantTrimmedStringExpr(value) {
@@ -4944,6 +5029,139 @@ function resolveAssistantGenericTimeGrain(message) {
4944
5029
  }
4945
5030
  return null;
4946
5031
  }
5032
+ function resolveAssistantBlendThroughputWindowDays(message) {
5033
+ var window = resolveAssistantGenericWindow(message);
5034
+ if (!window) {
5035
+ return null;
5036
+ }
5037
+ var amount = Math.max((0, common_1.round)(window.amount || 0), 1);
5038
+ switch (window.unit) {
5039
+ case 'day':
5040
+ return amount;
5041
+ case 'week':
5042
+ return amount * 7;
5043
+ case 'month':
5044
+ return amount * 30;
5045
+ case 'year':
5046
+ return amount * 365;
5047
+ default:
5048
+ return null;
5049
+ }
5050
+ }
5051
+ function shouldUseAssistantBlendThroughputHeuristic(message) {
5052
+ var normalized = normalizeOptionalString(message).toLowerCase();
5053
+ if (!normalized) {
5054
+ return false;
5055
+ }
5056
+ if (!/\bblend(?:ing|s)?\b/.test(normalized)) {
5057
+ return false;
5058
+ }
5059
+ if (!/\b(throughput|volume|output)\b/.test(normalized)) {
5060
+ return false;
5061
+ }
5062
+ var requestedGrain = resolveAssistantRequestedTimeGrain(message);
5063
+ var genericGrain = resolveAssistantGenericTimeGrain(message);
5064
+ var grain = requestedGrain || genericGrain;
5065
+ if (grain && grain !== 'day') {
5066
+ return false;
5067
+ }
5068
+ if (/\b(by|per|each)\s+day\b|\bdaily\b/.test(normalized)) {
5069
+ return true;
5070
+ }
5071
+ return !grain;
5072
+ }
5073
+ function buildAssistantBlendThroughputDirective(message) {
5074
+ if (!shouldUseAssistantBlendThroughputHeuristic(message)) {
5075
+ return null;
5076
+ }
5077
+ var resolvedDays = resolveAssistantBlendThroughputWindowDays(message);
5078
+ if (!resolvedDays || resolvedDays <= 0) {
5079
+ return null;
5080
+ }
5081
+ var windowDays = Math.min(Math.max((0, common_1.round)(resolvedDays), 1), 366);
5082
+ var startOfDayExpr = { $dateTrunc: { date: '$$NOW', unit: 'day' } };
5083
+ return {
5084
+ type: 'aggregate',
5085
+ payload: {
5086
+ collection: 'chemical-blends',
5087
+ permissionView: '/chemical-blend/list',
5088
+ pipeline: [
5089
+ {
5090
+ $match: {
5091
+ $and: [
5092
+ { 'deleted.is_deleted': false },
5093
+ {
5094
+ $expr: {
5095
+ $and: [
5096
+ {
5097
+ $gte: [
5098
+ '$date',
5099
+ {
5100
+ $dateSubtract: {
5101
+ startDate: startOfDayExpr,
5102
+ unit: 'day',
5103
+ amount: windowDays
5104
+ }
5105
+ }
5106
+ ]
5107
+ },
5108
+ {
5109
+ $lt: [
5110
+ '$date',
5111
+ startOfDayExpr
5112
+ ]
5113
+ }
5114
+ ]
5115
+ }
5116
+ }
5117
+ ]
5118
+ }
5119
+ },
5120
+ {
5121
+ $group: {
5122
+ _id: {
5123
+ day: {
5124
+ $dateTrunc: {
5125
+ date: '$date',
5126
+ unit: 'day'
5127
+ }
5128
+ }
5129
+ },
5130
+ total_gal: {
5131
+ $sum: {
5132
+ $ifNull: ['$quantity', 0]
5133
+ }
5134
+ },
5135
+ total_lb: {
5136
+ $sum: {
5137
+ $ifNull: ['$quantity_pounds', 0]
5138
+ }
5139
+ }
5140
+ }
5141
+ },
5142
+ {
5143
+ $project: {
5144
+ _id: 0,
5145
+ day: '$_id.day',
5146
+ total_gal: 1,
5147
+ total_lb: 1
5148
+ }
5149
+ },
5150
+ {
5151
+ $sort: {
5152
+ day: 1
5153
+ }
5154
+ }
5155
+ ],
5156
+ options: {
5157
+ allowDiskUse: true,
5158
+ limit: Math.min(windowDays + 6, 400)
5159
+ }
5160
+ },
5161
+ cleaned: '',
5162
+ rawLine: 'HEURISTIC_AGG(blend-throughput-day-window)'
5163
+ };
5164
+ }
4947
5165
  function resolveAssistantGenericPersonName(message) {
4948
5166
  var e_4, _a;
4949
5167
  var raw = normalizeOptionalString(message);
@@ -5410,13 +5628,22 @@ function isAssistantSchemaHoursHeuristicDirective(directive) {
5410
5628
  var rawLine = normalizeOptionalString(directive === null || directive === void 0 ? void 0 : directive.rawLine).toLowerCase();
5411
5629
  return rawLine.includes('heuristic_agg(schema-hours-user-time)');
5412
5630
  }
5631
+ function isAssistantBlendThroughputHeuristicDirective(directive) {
5632
+ var rawLine = normalizeOptionalString(directive === null || directive === void 0 ? void 0 : directive.rawLine).toLowerCase();
5633
+ return rawLine.includes('heuristic_agg(blend-throughput-day-window)');
5634
+ }
5413
5635
  function isAssistantDeterministicHeuristicDirective(directive) {
5414
- return isAssistantSchemaHoursHeuristicDirective(directive);
5636
+ return isAssistantSchemaHoursHeuristicDirective(directive)
5637
+ || isAssistantBlendThroughputHeuristicDirective(directive);
5415
5638
  }
5416
5639
  function buildAssistantHeuristicDirective(message, collectionHints) {
5417
5640
  if (!normalizeOptionalString(message)) {
5418
5641
  return null;
5419
5642
  }
5643
+ var blendThroughputDirective = buildAssistantBlendThroughputDirective(message);
5644
+ if (blendThroughputDirective) {
5645
+ return blendThroughputDirective;
5646
+ }
5420
5647
  var schemaHoursDirective = buildAssistantGenericHoursDirective(message, collectionHints);
5421
5648
  if (schemaHoursDirective) {
5422
5649
  return schemaHoursDirective;
@@ -6866,63 +7093,74 @@ function tokenizeFieldKey(value) {
6866
7093
  function normalizeFieldMatchKey(value) {
6867
7094
  return tokenizeFieldKey(value).join('');
6868
7095
  }
6869
- function getCollectionSchemaFieldNames(collectionName) {
7096
+ function getAssistantCollectionMetadata(collectionName) {
6870
7097
  var _a;
6871
7098
  var normalized = normalizeOptionalString(collectionName);
6872
7099
  if (!normalized) {
6873
- return [];
7100
+ return { fields: [], lookups: [] };
7101
+ }
7102
+ var now = Date.now();
7103
+ var cached = AI_ASSISTANT_COLLECTION_METADATA_CACHE.get(normalized);
7104
+ if (cached && now - cached.updatedAt < AI_ASSISTANT_COLLECTION_METADATA_CACHE_TTL_MS) {
7105
+ return {
7106
+ fields: cached.fields,
7107
+ lookups: cached.lookups
7108
+ };
6874
7109
  }
6875
7110
  try {
6876
7111
  var collection = (_a = resolveio_server_app_1.ResolveIOServer.getMongoManager()) === null || _a === void 0 ? void 0 : _a.collection(normalized);
6877
7112
  var schema = collection === null || collection === void 0 ? void 0 : collection.simplschema;
6878
- var fields_1 = schema && typeof schema.schema === 'function'
6879
- ? Object.keys(schema.schema())
6880
- : [];
6881
- var rbSchema = collection === null || collection === void 0 ? void 0 : collection.rbSchema;
6882
- if (rbSchema && typeof rbSchema === 'object') {
6883
- Object.keys(rbSchema).forEach(function (field) {
6884
- if (field && !fields_1.includes(field)) {
6885
- fields_1.push(field);
7113
+ var rbSchema_1 = collection === null || collection === void 0 ? void 0 : collection.rbSchema;
7114
+ var fieldSet_1 = new Set();
7115
+ var lookups_1 = [];
7116
+ if (schema && typeof schema.schema === 'function') {
7117
+ Object.keys(schema.schema()).forEach(function (field) {
7118
+ var normalizedField = normalizeOptionalString(field);
7119
+ if (normalizedField) {
7120
+ fieldSet_1.add(normalizedField);
7121
+ }
7122
+ });
7123
+ }
7124
+ if (rbSchema_1 && typeof rbSchema_1 === 'object') {
7125
+ Object.keys(rbSchema_1).forEach(function (field) {
7126
+ var normalizedField = normalizeOptionalString(field);
7127
+ if (normalizedField) {
7128
+ fieldSet_1.add(normalizedField);
7129
+ }
7130
+ var entry = rbSchema_1[field];
7131
+ if (!entry || typeof entry !== 'object') {
7132
+ return;
7133
+ }
7134
+ var lookupCollection = normalizeOptionalString(entry.lookup_collection);
7135
+ var localKey = normalizeOptionalString(entry.local_key);
7136
+ if (!lookupCollection || !localKey) {
7137
+ return;
6886
7138
  }
7139
+ var lookupKey = normalizeOptionalString(entry.lookup_key) || '_id';
7140
+ lookups_1.push({ localKey: localKey, lookupCollection: lookupCollection, lookupKey: lookupKey });
6887
7141
  });
6888
7142
  }
6889
- return fields_1;
7143
+ var value = {
7144
+ fields: Array.from(fieldSet_1),
7145
+ lookups: lookups_1
7146
+ };
7147
+ AI_ASSISTANT_COLLECTION_METADATA_CACHE.set(normalized, __assign(__assign({}, value), { updatedAt: now }));
7148
+ return value;
6890
7149
  }
6891
7150
  catch (_b) {
6892
- return [];
7151
+ return cached
7152
+ ? {
7153
+ fields: cached.fields,
7154
+ lookups: cached.lookups
7155
+ }
7156
+ : { fields: [], lookups: [] };
6893
7157
  }
6894
7158
  }
7159
+ function getCollectionSchemaFieldNames(collectionName) {
7160
+ return getAssistantCollectionMetadata(collectionName).fields;
7161
+ }
6895
7162
  function getCollectionLookupMappings(collectionName) {
6896
- var _a;
6897
- var normalized = normalizeOptionalString(collectionName);
6898
- if (!normalized) {
6899
- return [];
6900
- }
6901
- try {
6902
- var collection = (_a = resolveio_server_app_1.ResolveIOServer.getMongoManager()) === null || _a === void 0 ? void 0 : _a.collection(normalized);
6903
- var rbSchema_1 = collection === null || collection === void 0 ? void 0 : collection.rbSchema;
6904
- if (!rbSchema_1 || typeof rbSchema_1 !== 'object') {
6905
- return [];
6906
- }
6907
- var mappings_1 = [];
6908
- Object.keys(rbSchema_1).forEach(function (key) {
6909
- var entry = rbSchema_1[key];
6910
- if (!entry || typeof entry !== 'object') {
6911
- return;
6912
- }
6913
- var lookupCollection = normalizeOptionalString(entry.lookup_collection);
6914
- var localKey = normalizeOptionalString(entry.local_key);
6915
- if (!lookupCollection || !localKey) {
6916
- return;
6917
- }
6918
- var lookupKey = normalizeOptionalString(entry.lookup_key) || '_id';
6919
- mappings_1.push({ localKey: localKey, lookupCollection: lookupCollection, lookupKey: lookupKey });
6920
- });
6921
- return mappings_1;
6922
- }
6923
- catch (_b) {
6924
- return [];
6925
- }
7163
+ return getAssistantCollectionMetadata(collectionName).lookups;
6926
7164
  }
6927
7165
  function normalizeLookupPath(value) {
6928
7166
  var trimmed = normalizeOptionalString(value);
@@ -7235,51 +7473,105 @@ function collectTopLevelIdFieldValues(docs, options) {
7235
7473
  });
7236
7474
  });
7237
7475
  }
7238
- function resolveLookupDisplayField(baseToken, probeDocs, schemaFields) {
7239
- var e_12, _a, e_13, _b;
7476
+ function resolveLookupDisplayFieldCandidates(baseToken, probeDocs, schemaFields) {
7240
7477
  var normalizedBase = normalizeOptionalString(baseToken);
7241
7478
  if (!normalizedBase) {
7242
- return null;
7479
+ return [];
7243
7480
  }
7244
- var candidates = buildNameLookupFields(normalizedBase, probeDocs || []);
7481
+ var seededCandidates = buildNameLookupFields(normalizedBase, probeDocs || []);
7245
7482
  var schema = Array.isArray(schemaFields) ? schemaFields : [];
7246
- if (schema.length) {
7247
- var schemaCandidates = candidates.filter(function (candidate) { return schema.includes(candidate); });
7248
- if (schemaCandidates.length) {
7249
- try {
7250
- for (var schemaCandidates_1 = __values(schemaCandidates), schemaCandidates_1_1 = schemaCandidates_1.next(); !schemaCandidates_1_1.done; schemaCandidates_1_1 = schemaCandidates_1.next()) {
7251
- var candidate = schemaCandidates_1_1.value;
7252
- if (hasNonEmptyValue(probeDocs || [], candidate, { treatObjectLikeAsEmpty: true })) {
7253
- return candidate;
7254
- }
7255
- }
7256
- }
7257
- catch (e_12_1) { e_12 = { error: e_12_1 }; }
7258
- finally {
7259
- try {
7260
- if (schemaCandidates_1_1 && !schemaCandidates_1_1.done && (_a = schemaCandidates_1.return)) _a.call(schemaCandidates_1);
7261
- }
7262
- finally { if (e_12) throw e_12.error; }
7263
- }
7264
- return schemaCandidates[0];
7483
+ var schemaCandidates = schema.filter(function (field) {
7484
+ var normalized = normalizeOptionalString(field).toLowerCase();
7485
+ if (!normalized) {
7486
+ return false;
7265
7487
  }
7266
- }
7267
- try {
7268
- for (var candidates_1 = __values(candidates), candidates_1_1 = candidates_1.next(); !candidates_1_1.done; candidates_1_1 = candidates_1.next()) {
7269
- var candidate = candidates_1_1.value;
7270
- if (hasNonEmptyValue(probeDocs || [], candidate, { treatObjectLikeAsEmpty: true })) {
7271
- return candidate;
7272
- }
7488
+ if (!/(name|label|title|display|billing|company|account|client|customer|full)/.test(normalized)) {
7489
+ return false;
7273
7490
  }
7274
- }
7275
- catch (e_13_1) { e_13 = { error: e_13_1 }; }
7276
- finally {
7277
- try {
7278
- if (candidates_1_1 && !candidates_1_1.done && (_b = candidates_1.return)) _b.call(candidates_1);
7491
+ return !/(^|\.)(id|code|number|count|qty|quantity|total)(\.|_|$)/.test(normalized);
7492
+ });
7493
+ var probeFieldStats = collectFieldCandidates(probeDocs || []);
7494
+ var probeCandidates = Array.from(probeFieldStats.entries())
7495
+ .filter(function (_a) {
7496
+ var _b = __read(_a, 2), stats = _b[1];
7497
+ return stats.nonEmpty > 0;
7498
+ })
7499
+ .map(function (_a) {
7500
+ var _b = __read(_a, 1), field = _b[0];
7501
+ return field;
7502
+ })
7503
+ .filter(function (field) {
7504
+ var normalized = normalizeOptionalString(field).toLowerCase();
7505
+ if (!normalized) {
7506
+ return false;
7507
+ }
7508
+ if (!/(name|label|title|display|billing|company|account|client|customer|full)/.test(normalized)) {
7509
+ return false;
7510
+ }
7511
+ return !/(^|\.)(id|code|number|count|qty|quantity|total)(\.|_|$)/.test(normalized);
7512
+ });
7513
+ return normalizeAggregateFieldList(__spreadArray(__spreadArray(__spreadArray([], __read(seededCandidates), false), __read(schemaCandidates), false), __read(probeCandidates), false)).slice(0, 24);
7514
+ }
7515
+ function scoreLookupDisplayFieldFromDocs(field, lookupDocs) {
7516
+ var docs = Array.isArray(lookupDocs) ? lookupDocs : [];
7517
+ var uniqueValues = new Set();
7518
+ var nonEmptyCount = 0;
7519
+ docs.forEach(function (doc) {
7520
+ var _a;
7521
+ var raw = (_a = getValueAtPath(doc, field)) !== null && _a !== void 0 ? _a : doc === null || doc === void 0 ? void 0 : doc[field];
7522
+ if (isEmptyDisplayValue(raw) || isDisplayObjectLike(raw)) {
7523
+ return;
7524
+ }
7525
+ var text = normalizeOptionalString(typeof raw === 'string' ? raw : String(raw));
7526
+ if (!text) {
7527
+ return;
7279
7528
  }
7280
- finally { if (e_13) throw e_13.error; }
7529
+ nonEmptyCount += 1;
7530
+ uniqueValues.add(text.toLowerCase());
7531
+ });
7532
+ var fillRate = docs.length ? (nonEmptyCount / docs.length) : 0;
7533
+ var uniqueCount = uniqueValues.size;
7534
+ var normalizedField = normalizeOptionalString(field).toLowerCase();
7535
+ var semanticBonus = 0;
7536
+ if (/billing_name|customer_name|client_name|company_name/.test(normalizedField)) {
7537
+ semanticBonus += 18;
7538
+ }
7539
+ if (/(^|\.)(name|label|title|display_name|displayname|fullname|full_name)(\.|_|$)/.test(normalizedField)) {
7540
+ semanticBonus += 12;
7541
+ }
7542
+ if (/(^|\.)(id|code|number|count|qty|quantity|total)(\.|_|$)/.test(normalizedField)) {
7543
+ semanticBonus -= 20;
7544
+ }
7545
+ var score = (fillRate * 100) + (Math.min(uniqueCount, nonEmptyCount) * 3) + semanticBonus;
7546
+ return {
7547
+ field: field,
7548
+ score: score,
7549
+ fillRate: fillRate,
7550
+ uniqueCount: uniqueCount,
7551
+ nonEmptyCount: nonEmptyCount
7552
+ };
7553
+ }
7554
+ function resolveBestLookupDisplayFieldFromDocs(candidates, lookupDocs) {
7555
+ var normalizedCandidates = normalizeAggregateFieldList(candidates || []);
7556
+ if (!normalizedCandidates.length) {
7557
+ return null;
7281
7558
  }
7282
- return candidates.length ? candidates[0] : null;
7559
+ var ranked = normalizedCandidates
7560
+ .map(function (field) { return scoreLookupDisplayFieldFromDocs(field, lookupDocs); })
7561
+ .filter(function (entry) { return entry.nonEmptyCount > 0; })
7562
+ .sort(function (a, b) {
7563
+ if (a.score !== b.score) {
7564
+ return b.score - a.score;
7565
+ }
7566
+ if (a.fillRate !== b.fillRate) {
7567
+ return b.fillRate - a.fillRate;
7568
+ }
7569
+ if (a.uniqueCount !== b.uniqueCount) {
7570
+ return b.uniqueCount - a.uniqueCount;
7571
+ }
7572
+ return a.field.localeCompare(b.field);
7573
+ });
7574
+ return ranked[0] || null;
7283
7575
  }
7284
7576
  function resolveLookupMappingsForField(field, mappings) {
7285
7577
  var normalizedField = normalizeLookupPath(field);
@@ -7290,8 +7582,8 @@ function resolveLookupMappingsForField(field, mappings) {
7290
7582
  }
7291
7583
  function applyIdLookupDisplayEnrichment(params) {
7292
7584
  return __awaiter(this, void 0, void 0, function () {
7293
- var docs, collection, db, dbName, idClient, idCustomer, isSuperAdmin, idFields, lookupMappings, allCollections, collectionProbeCache, collectionSchemaCache, lookupMeta, enrichedDocs, _loop_4, idFields_1, idFields_1_1, fieldEntry, e_14_1;
7294
- var e_14, _a;
7585
+ var docs, collection, db, dbName, idClient, idCustomer, isSuperAdmin, idFields, lookupMappings, allCollections, collectionProbeCache, collectionSchemaCache, lookupMeta, enrichedDocs, _loop_4, idFields_1, idFields_1_1, fieldEntry, e_12_1;
7586
+ var e_12, _a;
7295
7587
  return __generator(this, function (_b) {
7296
7588
  switch (_b.label) {
7297
7589
  case 0:
@@ -7315,8 +7607,8 @@ function applyIdLookupDisplayEnrichment(params) {
7315
7607
  lookupMeta = [];
7316
7608
  enrichedDocs = docs.map(function (doc) { return (__assign({}, doc)); });
7317
7609
  _loop_4 = function (fieldEntry) {
7318
- var values, baseToken, mappingMatches, candidateCollections, filteredCandidates, _loop_5, filteredCandidates_1, filteredCandidates_1_1, candidate, state_3, e_15_1;
7319
- var e_15, _c;
7610
+ var values, baseToken, mappingMatches, candidateCollections, filteredCandidates, _loop_5, filteredCandidates_1, filteredCandidates_1_1, candidate, state_3, e_13_1;
7611
+ var e_13, _c;
7320
7612
  return __generator(this, function (_d) {
7321
7613
  switch (_d.label) {
7322
7614
  case 0:
@@ -7342,7 +7634,7 @@ function applyIdLookupDisplayEnrichment(params) {
7342
7634
  return [2 /*return*/, "continue"];
7343
7635
  }
7344
7636
  _loop_5 = function (candidate) {
7345
- var probeDocs, candidateHasClientScope, _e, schemaFields, nameField, mapping, lookupKey, idsForQuery, query, candidateHasClientScope, _f, lookupDocs, nameMap, displayField;
7637
+ var probeDocs, candidateHasClientScope, _e, schemaFields, nameFieldCandidates, mapping, lookupKey, idsForQuery, query, candidateHasClientScope, _f, projection, lookupDocs, bestLookupField, nameField, nameMap, displayField;
7346
7638
  var _g, _h;
7347
7639
  return __generator(this, function (_j) {
7348
7640
  switch (_j.label) {
@@ -7375,8 +7667,8 @@ function applyIdLookupDisplayEnrichment(params) {
7375
7667
  schemaFields = collectionSchemaCache.get(candidate)
7376
7668
  || getCollectionSchemaFieldNames(candidate);
7377
7669
  collectionSchemaCache.set(candidate, schemaFields);
7378
- nameField = resolveLookupDisplayField(baseToken, probeDocs, schemaFields);
7379
- if (!nameField) {
7670
+ nameFieldCandidates = resolveLookupDisplayFieldCandidates(baseToken, probeDocs, schemaFields);
7671
+ if (!nameFieldCandidates.length) {
7380
7672
  return [2 /*return*/, "continue"];
7381
7673
  }
7382
7674
  mapping = mappingMatches.find(function (entry) { return entry.lookupCollection === candidate; });
@@ -7402,16 +7694,26 @@ function applyIdLookupDisplayEnrichment(params) {
7402
7694
  }
7403
7695
  query = applyCustomerScopeFilter(query, candidate, idCustomer, isSuperAdmin);
7404
7696
  _j.label = 9;
7405
- case 9: return [4 /*yield*/, db.collection(candidate).find(query, {
7406
- projection: (_h = {}, _h[lookupKey] = 1, _h[nameField] = 1, _h),
7407
- limit: AI_ASSISTANT_ID_DISPLAY_LOOKUP_MAX_IDS,
7408
- readPreference: AI_ASSISTANT_READ_PREFERENCE
7409
- }).toArray()];
7697
+ case 9:
7698
+ projection = (_h = {}, _h[lookupKey] = 1, _h);
7699
+ nameFieldCandidates.forEach(function (field) {
7700
+ projection[field] = 1;
7701
+ });
7702
+ return [4 /*yield*/, db.collection(candidate).find(query, {
7703
+ projection: projection,
7704
+ limit: AI_ASSISTANT_ID_DISPLAY_LOOKUP_MAX_IDS,
7705
+ readPreference: AI_ASSISTANT_READ_PREFERENCE
7706
+ }).toArray()];
7410
7707
  case 10:
7411
7708
  lookupDocs = _j.sent();
7412
7709
  if (!lookupDocs.length) {
7413
7710
  return [2 /*return*/, "continue"];
7414
7711
  }
7712
+ bestLookupField = resolveBestLookupDisplayFieldFromDocs(nameFieldCandidates, lookupDocs);
7713
+ if (!(bestLookupField === null || bestLookupField === void 0 ? void 0 : bestLookupField.field)) {
7714
+ return [2 /*return*/, "continue"];
7715
+ }
7716
+ nameField = bestLookupField.field;
7415
7717
  nameMap = new Map();
7416
7718
  lookupDocs.forEach(function (doc) {
7417
7719
  var _a, _b;
@@ -7454,6 +7756,9 @@ function applyIdLookupDisplayEnrichment(params) {
7454
7756
  displayField: displayField,
7455
7757
  collection: candidate,
7456
7758
  nameField: nameField,
7759
+ nameFieldFillRate: (0, common_1.round)(bestLookupField.fillRate * 100, 2),
7760
+ nameFieldUniqueValues: bestLookupField.uniqueCount,
7761
+ candidateFieldsTested: nameFieldCandidates.length,
7457
7762
  idCount: values.length,
7458
7763
  matched: nameMap.size,
7459
7764
  strategy: mapping ? 'schema' : 'token'
@@ -7465,7 +7770,7 @@ function applyIdLookupDisplayEnrichment(params) {
7465
7770
  _d.label = 1;
7466
7771
  case 1:
7467
7772
  _d.trys.push([1, 6, 7, 8]);
7468
- filteredCandidates_1 = (e_15 = void 0, __values(filteredCandidates)), filteredCandidates_1_1 = filteredCandidates_1.next();
7773
+ filteredCandidates_1 = (e_13 = void 0, __values(filteredCandidates)), filteredCandidates_1_1 = filteredCandidates_1.next();
7469
7774
  _d.label = 2;
7470
7775
  case 2:
7471
7776
  if (!!filteredCandidates_1_1.done) return [3 /*break*/, 5];
@@ -7481,14 +7786,14 @@ function applyIdLookupDisplayEnrichment(params) {
7481
7786
  return [3 /*break*/, 2];
7482
7787
  case 5: return [3 /*break*/, 8];
7483
7788
  case 6:
7484
- e_15_1 = _d.sent();
7485
- e_15 = { error: e_15_1 };
7789
+ e_13_1 = _d.sent();
7790
+ e_13 = { error: e_13_1 };
7486
7791
  return [3 /*break*/, 8];
7487
7792
  case 7:
7488
7793
  try {
7489
7794
  if (filteredCandidates_1_1 && !filteredCandidates_1_1.done && (_c = filteredCandidates_1.return)) _c.call(filteredCandidates_1);
7490
7795
  }
7491
- finally { if (e_15) throw e_15.error; }
7796
+ finally { if (e_13) throw e_13.error; }
7492
7797
  return [7 /*endfinally*/];
7493
7798
  case 8: return [2 /*return*/];
7494
7799
  }
@@ -7511,14 +7816,14 @@ function applyIdLookupDisplayEnrichment(params) {
7511
7816
  return [3 /*break*/, 3];
7512
7817
  case 6: return [3 /*break*/, 9];
7513
7818
  case 7:
7514
- e_14_1 = _b.sent();
7515
- e_14 = { error: e_14_1 };
7819
+ e_12_1 = _b.sent();
7820
+ e_12 = { error: e_12_1 };
7516
7821
  return [3 /*break*/, 9];
7517
7822
  case 8:
7518
7823
  try {
7519
7824
  if (idFields_1_1 && !idFields_1_1.done && (_a = idFields_1.return)) _a.call(idFields_1);
7520
7825
  }
7521
- finally { if (e_14) throw e_14.error; }
7826
+ finally { if (e_12) throw e_12.error; }
7522
7827
  return [7 /*endfinally*/];
7523
7828
  case 9:
7524
7829
  if (!lookupMeta.length) {
@@ -7537,7 +7842,7 @@ function applyIdLookupDisplayEnrichment(params) {
7537
7842
  });
7538
7843
  }
7539
7844
  function hasNonEmptyValue(docs, fieldPath, options) {
7540
- var e_16, _a;
7845
+ var e_14, _a;
7541
7846
  if (!Array.isArray(docs) || !fieldPath) {
7542
7847
  return false;
7543
7848
  }
@@ -7554,12 +7859,12 @@ function hasNonEmptyValue(docs, fieldPath, options) {
7554
7859
  }
7555
7860
  }
7556
7861
  }
7557
- catch (e_16_1) { e_16 = { error: e_16_1 }; }
7862
+ catch (e_14_1) { e_14 = { error: e_14_1 }; }
7558
7863
  finally {
7559
7864
  try {
7560
7865
  if (docs_4_1 && !docs_4_1.done && (_a = docs_4.return)) _a.call(docs_4);
7561
7866
  }
7562
- finally { if (e_16) throw e_16.error; }
7867
+ finally { if (e_14) throw e_14.error; }
7563
7868
  }
7564
7869
  return false;
7565
7870
  }
@@ -8336,7 +8641,7 @@ function isAssistantCurrencyColumn(column) {
8336
8641
  return hasMoneyHint;
8337
8642
  }
8338
8643
  function isAssistantDateColumn(column) {
8339
- return /(date|time|created|updated|timestamp|at)\b/.test(column);
8644
+ return /(date|day|week|time|created|updated|timestamp|period)\b/.test(column) || /_at\b/.test(column);
8340
8645
  }
8341
8646
  function isAssistantLikelyDateValue(value) {
8342
8647
  if (!value) {
@@ -8346,10 +8651,17 @@ function isAssistantLikelyDateValue(value) {
8346
8651
  return true;
8347
8652
  }
8348
8653
  if (typeof value === 'string') {
8349
- if (!/[0-9]/.test(value)) {
8654
+ var normalized = value.trim();
8655
+ if (!normalized || !/[0-9]/.test(normalized)) {
8656
+ return false;
8657
+ }
8658
+ if (/^\d{1,6}$/.test(normalized) || /^\d{4}$/.test(normalized)) {
8659
+ return false;
8660
+ }
8661
+ if (!/[-/:T\s]/.test(normalized) && !/^\d{8}$/.test(normalized)) {
8350
8662
  return false;
8351
8663
  }
8352
- var parsed = Date.parse(value);
8664
+ var parsed = Date.parse(normalized);
8353
8665
  return !Number.isNaN(parsed);
8354
8666
  }
8355
8667
  return false;
@@ -9549,6 +9861,23 @@ function isAssistantDottedOutputFieldError(error) {
9549
9861
  }
9550
9862
  return message.includes("fieldpath field names may not contain '.'");
9551
9863
  }
9864
+ function extractAssistantDottedFieldPathFromError(error) {
9865
+ var message = normalizeOptionalString(error === null || error === void 0 ? void 0 : error.message);
9866
+ if (!message) {
9867
+ return null;
9868
+ }
9869
+ var quotedMatch = message.match(/given\s+'([^']+)'/i);
9870
+ if (quotedMatch && quotedMatch[1]) {
9871
+ var normalized = normalizeOptionalString(quotedMatch[1]);
9872
+ return normalized.includes('.') ? normalized : null;
9873
+ }
9874
+ var plainMatch = message.match(/given\s+([a-z0-9_.-]+)/i);
9875
+ if (plainMatch && plainMatch[1]) {
9876
+ var normalized = normalizeOptionalString(plainMatch[1]);
9877
+ return normalized.includes('.') ? normalized : null;
9878
+ }
9879
+ return null;
9880
+ }
9552
9881
  function didAssistantValueChange(before, after) {
9553
9882
  try {
9554
9883
  return JSON.stringify(before) !== JSON.stringify(after);
@@ -9637,6 +9966,59 @@ function repairAssistantDottedOutputFieldNamesInPipeline(pipeline) {
9637
9966
  changed: didAssistantValueChange(pipeline, repaired)
9638
9967
  };
9639
9968
  }
9969
+ function buildAssistantGetFieldExpressionFromPath(path) {
9970
+ var normalizedPath = normalizeOptionalString(path);
9971
+ var segments = normalizedPath.split('.').filter(Boolean);
9972
+ if (!segments.length) {
9973
+ return "$".concat(normalizedPath);
9974
+ }
9975
+ var expression = "$".concat(segments[0]);
9976
+ for (var i = 1; i < segments.length; i += 1) {
9977
+ expression = {
9978
+ $getField: {
9979
+ field: segments[i],
9980
+ input: expression
9981
+ }
9982
+ };
9983
+ }
9984
+ return expression;
9985
+ }
9986
+ function repairAssistantFieldPathReferenceInPipeline(pipeline, fieldPath) {
9987
+ var normalizedFieldPath = normalizeOptionalString(fieldPath).replace(/^\$+/, '');
9988
+ if (!normalizedFieldPath || !normalizedFieldPath.includes('.')) {
9989
+ return { pipeline: pipeline, changed: false };
9990
+ }
9991
+ var targetRef = "$".concat(normalizedFieldPath);
9992
+ var rewriteValue = function (value) {
9993
+ if (Array.isArray(value)) {
9994
+ return value.map(function (entry) { return rewriteValue(entry); });
9995
+ }
9996
+ if (typeof value === 'string') {
9997
+ if (value === targetRef) {
9998
+ return buildAssistantGetFieldExpressionFromPath(normalizedFieldPath);
9999
+ }
10000
+ if (value.startsWith("".concat(targetRef, "."))) {
10001
+ return buildAssistantGetFieldExpressionFromPath(value.slice(1));
10002
+ }
10003
+ return value;
10004
+ }
10005
+ if (!value || typeof value !== 'object' || value instanceof Date || value instanceof RegExp || isMongoObjectId(value)) {
10006
+ return value;
10007
+ }
10008
+ var next = {};
10009
+ Object.keys(value).forEach(function (key) {
10010
+ next[key] = rewriteValue(value[key]);
10011
+ });
10012
+ return next;
10013
+ };
10014
+ var repaired = Array.isArray(pipeline)
10015
+ ? pipeline.map(function (stage) { return rewriteValue(stage); })
10016
+ : pipeline;
10017
+ return {
10018
+ pipeline: repaired,
10019
+ changed: didAssistantValueChange(pipeline, repaired)
10020
+ };
10021
+ }
9640
10022
  function isMatchExpressionOperand(value) {
9641
10023
  if (typeof value === 'string') {
9642
10024
  return value.startsWith('$$');
@@ -9899,7 +10281,7 @@ function flattenAssistantExprClauses(expr) {
9899
10281
  return [expr];
9900
10282
  }
9901
10283
  function detectAssistantMonthWindowInExpr(expr, allowedDateFields) {
9902
- var e_17, _a;
10284
+ var e_15, _a;
9903
10285
  var clauses = flattenAssistantExprClauses(expr);
9904
10286
  if (!clauses.length) {
9905
10287
  return null;
@@ -9973,12 +10355,12 @@ function detectAssistantMonthWindowInExpr(expr, allowedDateFields) {
9973
10355
  return state_4.value;
9974
10356
  }
9975
10357
  }
9976
- catch (e_17_1) { e_17 = { error: e_17_1 }; }
10358
+ catch (e_15_1) { e_15 = { error: e_15_1 }; }
9977
10359
  finally {
9978
10360
  try {
9979
10361
  if (lowerClauses_1_1 && !lowerClauses_1_1.done && (_a = lowerClauses_1.return)) _a.call(lowerClauses_1);
9980
10362
  }
9981
- finally { if (e_17) throw e_17.error; }
10363
+ finally { if (e_15) throw e_15.error; }
9982
10364
  }
9983
10365
  return null;
9984
10366
  }
@@ -10041,7 +10423,7 @@ function resolveAssistantMonthlyGroupDateFields(pipeline) {
10041
10423
  return fields;
10042
10424
  }
10043
10425
  function detectAssistantMonthWindowFromPipeline(pipeline) {
10044
- var e_18, _a;
10426
+ var e_16, _a;
10045
10427
  var _b;
10046
10428
  var monthlyFields = resolveAssistantMonthlyGroupDateFields(pipeline);
10047
10429
  var scanMatch = function (match) {
@@ -10069,12 +10451,12 @@ function detectAssistantMonthWindowFromPipeline(pipeline) {
10069
10451
  }
10070
10452
  }
10071
10453
  }
10072
- catch (e_18_1) { e_18 = { error: e_18_1 }; }
10454
+ catch (e_16_1) { e_16 = { error: e_16_1 }; }
10073
10455
  finally {
10074
10456
  try {
10075
10457
  if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
10076
10458
  }
10077
- finally { if (e_18) throw e_18.error; }
10459
+ finally { if (e_16) throw e_16.error; }
10078
10460
  }
10079
10461
  return null;
10080
10462
  }
@@ -10178,7 +10560,234 @@ function normalizeAssistantSortTieBreakersForLimit(pipeline) {
10178
10560
  return __assign(__assign({}, stage), { $sort: __assign(__assign({}, sort), { _id: 1 }) });
10179
10561
  });
10180
10562
  }
10181
- function normalizeAssistantAggregatePipeline(pipeline, collection) {
10563
+ function resolveAssistantRecentGroupedRecordLimit(message) {
10564
+ var normalized = normalizeOptionalString(message);
10565
+ if (!normalized) {
10566
+ return null;
10567
+ }
10568
+ if (!/\b(last|latest|recent)\b/i.test(normalized)) {
10569
+ return null;
10570
+ }
10571
+ var groupedHint = /\bgroup(?:ed|ing)?\s+by\b/i.test(normalized)
10572
+ || /\bby\s+(status|state|type)\b/i.test(normalized);
10573
+ if (!groupedHint) {
10574
+ return null;
10575
+ }
10576
+ if (/\b(by|per)\s+(day|week|month|quarter|year)\b/i.test(normalized) || /\btrend|over\s+time|timeline\b/i.test(normalized)) {
10577
+ return null;
10578
+ }
10579
+ var tokenMatch = normalized.match(/\b(?:last|latest|recent)\s+(\d{1,4})\s+([a-z][a-z_-]*)\b/i);
10580
+ if (!tokenMatch) {
10581
+ return null;
10582
+ }
10583
+ var entityToken = normalizeOptionalString(tokenMatch[2]).toLowerCase();
10584
+ if (['minute', 'minutes', 'hour', 'hours', 'day', 'days', 'week', 'weeks', 'month', 'months', 'quarter', 'quarters', 'year', 'years'].includes(entityToken)) {
10585
+ return null;
10586
+ }
10587
+ var value = Number(tokenMatch[1]);
10588
+ if (!Number.isFinite(value) || value <= 0) {
10589
+ return null;
10590
+ }
10591
+ return Math.max(1, Math.min((0, common_1.round)(value), AI_ASSISTANT_MONGO_MAX_LIMIT));
10592
+ }
10593
+ function normalizeAssistantRecentGroupedLimitBeforeGroup(pipeline, message) {
10594
+ var _a;
10595
+ var requestedLimit = resolveAssistantRecentGroupedRecordLimit(message || '');
10596
+ if (!requestedLimit || !Array.isArray(pipeline) || !pipeline.length) {
10597
+ return pipeline;
10598
+ }
10599
+ var groupIndex = findAggregateGroupIndex(pipeline);
10600
+ if (groupIndex <= 0) {
10601
+ return pipeline;
10602
+ }
10603
+ var hasPreGroupLimit = pipeline
10604
+ .slice(0, groupIndex)
10605
+ .some(function (stage) { return stage && typeof stage === 'object' && typeof stage.$limit === 'number' && stage.$limit > 0; });
10606
+ if (hasPreGroupLimit) {
10607
+ return pipeline;
10608
+ }
10609
+ var postGroupLimitIndex = pipeline.findIndex(function (stage, index) {
10610
+ return index > groupIndex
10611
+ && stage
10612
+ && typeof stage === 'object'
10613
+ && typeof stage.$limit === 'number'
10614
+ && stage.$limit > 0;
10615
+ });
10616
+ var nextPipeline = pipeline
10617
+ .map(function (stage) { return (stage && typeof stage === 'object' && !Array.isArray(stage) ? __assign({}, stage) : stage); })
10618
+ .filter(function (_stage, index) { return index !== postGroupLimitIndex; });
10619
+ var insertionIndex = groupIndex;
10620
+ var hasPreGroupSort = nextPipeline
10621
+ .slice(0, groupIndex)
10622
+ .some(function (stage) { return stage && typeof stage === 'object' && stage.$sort && typeof stage.$sort === 'object'; });
10623
+ if (!hasPreGroupSort) {
10624
+ var dateField = findAggregateDateField(nextPipeline) || 'createdAt';
10625
+ nextPipeline.splice(insertionIndex, 0, { $sort: (_a = {}, _a[dateField] = -1, _a._id = -1, _a) });
10626
+ insertionIndex += 1;
10627
+ }
10628
+ nextPipeline.splice(insertionIndex, 0, { $limit: requestedLimit });
10629
+ return nextPipeline;
10630
+ }
10631
+ function isAssistantCustomerLookupCollectionName(value) {
10632
+ var normalized = normalizeOptionalString(value).toLowerCase();
10633
+ if (!normalized) {
10634
+ return false;
10635
+ }
10636
+ return /(customer|client|account)/.test(normalized);
10637
+ }
10638
+ function isAssistantCustomerLabelFieldName(field) {
10639
+ var normalized = normalizeOptionalString(field).toLowerCase();
10640
+ if (!normalized) {
10641
+ return false;
10642
+ }
10643
+ return /(customer|client|account|company)/.test(normalized)
10644
+ && !/(id|count|number|qty|quantity|total)/.test(normalized);
10645
+ }
10646
+ function isAssistantCustomerLookupLeafName(path) {
10647
+ var normalized = normalizeOptionalString(path).toLowerCase();
10648
+ if (!normalized) {
10649
+ return false;
10650
+ }
10651
+ var leaf = normalized.split('.').pop() || normalized;
10652
+ return /(name|billing|company|display|label|title|account|client|customer|full)/.test(leaf)
10653
+ && !/(id|count|number|qty|quantity|total)/.test(leaf);
10654
+ }
10655
+ function buildAssistantCustomerLookupBestLabelExpr(lookupAlias, fallbackPaths) {
10656
+ var alias = normalizeOptionalString(lookupAlias);
10657
+ if (!alias) {
10658
+ return buildAssistantTrimmedStringExpr('$id_customer');
10659
+ }
10660
+ var aliasPrefix = "$".concat(alias);
10661
+ var candidatePaths = normalizeAggregateFieldList(__spreadArray([
10662
+ "".concat(aliasPrefix, ".billing_name"),
10663
+ "".concat(aliasPrefix, ".customer_name"),
10664
+ "".concat(aliasPrefix, ".name"),
10665
+ "".concat(aliasPrefix, ".fullname"),
10666
+ "".concat(aliasPrefix, ".full_name"),
10667
+ "".concat(aliasPrefix, ".display_name"),
10668
+ "".concat(aliasPrefix, ".displayName"),
10669
+ "".concat(aliasPrefix, ".label"),
10670
+ "".concat(aliasPrefix, ".title"),
10671
+ "".concat(aliasPrefix, ".company_name"),
10672
+ "".concat(aliasPrefix, ".company"),
10673
+ "".concat(aliasPrefix, ".client_name"),
10674
+ "".concat(aliasPrefix, ".clientName"),
10675
+ "".concat(aliasPrefix, ".account_name"),
10676
+ "".concat(aliasPrefix, ".accountName"),
10677
+ "".concat(aliasPrefix, ".quickbooks.FullName"),
10678
+ "".concat(aliasPrefix, ".quickbooks.fullname"),
10679
+ "".concat(aliasPrefix, ".quickbooks.Name"),
10680
+ "".concat(aliasPrefix, ".quickbooks.name")
10681
+ ], __read(fallbackPaths), false));
10682
+ var candidateValues = candidatePaths.map(function (path) { return buildAssistantTrimmedStringExpr(path); });
10683
+ return {
10684
+ $let: {
10685
+ vars: {
10686
+ candidate_values: candidateValues
10687
+ },
10688
+ in: {
10689
+ $ifNull: [
10690
+ {
10691
+ $arrayElemAt: [
10692
+ {
10693
+ $filter: {
10694
+ input: '$$candidate_values',
10695
+ as: 'candidate',
10696
+ cond: { $gt: [{ $strLenCP: '$$candidate' }, 0] }
10697
+ }
10698
+ },
10699
+ 0
10700
+ ]
10701
+ },
10702
+ ''
10703
+ ]
10704
+ }
10705
+ }
10706
+ };
10707
+ }
10708
+ function normalizeAssistantCustomerLookupProjectionPipeline(pipeline) {
10709
+ if (!Array.isArray(pipeline) || !pipeline.length) {
10710
+ return pipeline;
10711
+ }
10712
+ var lookupAliasToLocalField = new Map();
10713
+ var changed = false;
10714
+ var normalizedPipeline = pipeline.map(function (stage) { return (stage && typeof stage === 'object' && !Array.isArray(stage)
10715
+ ? __assign({}, stage) : stage); });
10716
+ normalizedPipeline.forEach(function (stage) {
10717
+ if (!stage || typeof stage !== 'object' || Array.isArray(stage)) {
10718
+ return;
10719
+ }
10720
+ var lookup = stage.$lookup;
10721
+ if (lookup && typeof lookup === 'object' && !Array.isArray(lookup)) {
10722
+ var lookupFrom = normalizeOptionalString(lookup.from);
10723
+ var lookupAlias = normalizeOptionalString(lookup.as);
10724
+ if (lookupAlias && isAssistantCustomerLookupCollectionName(lookupFrom)) {
10725
+ lookupAliasToLocalField.set(lookupAlias, normalizeOptionalString(lookup.localField));
10726
+ }
10727
+ return;
10728
+ }
10729
+ if (!lookupAliasToLocalField.size) {
10730
+ return;
10731
+ }
10732
+ var project = stage.$project;
10733
+ if (!project || typeof project !== 'object' || Array.isArray(project)) {
10734
+ return;
10735
+ }
10736
+ var nextProject = __assign({}, project);
10737
+ var stageChanged = false;
10738
+ Object.keys(nextProject).forEach(function (field) {
10739
+ var e_17, _a;
10740
+ var expression = nextProject[field];
10741
+ if (typeof expression !== 'string') {
10742
+ return;
10743
+ }
10744
+ var expressionPath = normalizeOptionalString(expression);
10745
+ if (!expressionPath || !expressionPath.startsWith('$')) {
10746
+ return;
10747
+ }
10748
+ try {
10749
+ for (var _b = __values(lookupAliasToLocalField.entries()), _c = _b.next(); !_c.done; _c = _b.next()) {
10750
+ var _d = __read(_c.value, 2), lookupAlias = _d[0], localField = _d[1];
10751
+ var aliasPath = "$".concat(lookupAlias);
10752
+ if (expressionPath !== aliasPath && !expressionPath.startsWith("".concat(aliasPath, "."))) {
10753
+ continue;
10754
+ }
10755
+ var lookupLeafPath = expressionPath === aliasPath
10756
+ ? ''
10757
+ : expressionPath.slice(aliasPath.length + 1);
10758
+ if (!isAssistantCustomerLabelFieldName(field) && !isAssistantCustomerLookupLeafName(lookupLeafPath)) {
10759
+ continue;
10760
+ }
10761
+ var fallbackPaths = normalizeAggregateFieldList([
10762
+ localField ? "$".concat(localField) : '',
10763
+ '$_id',
10764
+ '$id_customer',
10765
+ '$id_client',
10766
+ '$customer',
10767
+ '$customer_name',
10768
+ '$client_name'
10769
+ ]);
10770
+ nextProject[field] = buildAssistantCustomerLookupBestLabelExpr(lookupAlias, fallbackPaths);
10771
+ stageChanged = true;
10772
+ break;
10773
+ }
10774
+ }
10775
+ catch (e_17_1) { e_17 = { error: e_17_1 }; }
10776
+ finally {
10777
+ try {
10778
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
10779
+ }
10780
+ finally { if (e_17) throw e_17.error; }
10781
+ }
10782
+ });
10783
+ if (stageChanged) {
10784
+ stage.$project = nextProject;
10785
+ changed = true;
10786
+ }
10787
+ });
10788
+ return changed ? normalizedPipeline : pipeline;
10789
+ }
10790
+ function normalizeAssistantAggregatePipeline(pipeline, collection, originalMessage) {
10182
10791
  if (!Array.isArray(pipeline)) {
10183
10792
  return [];
10184
10793
  }
@@ -10205,7 +10814,9 @@ function normalizeAssistantAggregatePipeline(pipeline, collection) {
10205
10814
  return normalizeAssistantNowExprPlaceholdersDeep(next);
10206
10815
  });
10207
10816
  var stableSortPipeline = normalizeAssistantSortTieBreakersForLimit(normalizedPipeline);
10208
- return normalizeAssistantMonthlyCalendarWindowPipeline(stableSortPipeline);
10817
+ var recordLimitedPipeline = normalizeAssistantRecentGroupedLimitBeforeGroup(stableSortPipeline, originalMessage);
10818
+ var customerLookupNormalizedPipeline = normalizeAssistantCustomerLookupProjectionPipeline(recordLimitedPipeline);
10819
+ return normalizeAssistantMonthlyCalendarWindowPipeline(customerLookupNormalizedPipeline);
10209
10820
  }
10210
10821
  function buildAssistantAggregatePipeline(query, pipeline) {
10211
10822
  var _a;
@@ -10334,7 +10945,7 @@ function matchContainsField(value, field) {
10334
10945
  });
10335
10946
  }
10336
10947
  function resolveAggregateCompletionFallback(pipeline) {
10337
- var e_19, _a;
10948
+ var e_18, _a;
10338
10949
  if (!Array.isArray(pipeline)) {
10339
10950
  return null;
10340
10951
  }
@@ -10347,7 +10958,7 @@ function resolveAggregateCompletionFallback(pipeline) {
10347
10958
  }
10348
10959
  var addFields = stage.$addFields;
10349
10960
  try {
10350
- for (var _b = (e_19 = void 0, __values(Object.keys(addFields))), _c = _b.next(); !_c.done; _c = _b.next()) {
10961
+ for (var _b = (e_18 = void 0, __values(Object.keys(addFields))), _c = _b.next(); !_c.done; _c = _b.next()) {
10351
10962
  var key = _c.value;
10352
10963
  if (!isCompletionFieldName(key)) {
10353
10964
  continue;
@@ -10361,12 +10972,12 @@ function resolveAggregateCompletionFallback(pipeline) {
10361
10972
  }
10362
10973
  }
10363
10974
  }
10364
- catch (e_19_1) { e_19 = { error: e_19_1 }; }
10975
+ catch (e_18_1) { e_18 = { error: e_18_1 }; }
10365
10976
  finally {
10366
10977
  try {
10367
10978
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
10368
10979
  }
10369
- finally { if (e_19) throw e_19.error; }
10980
+ finally { if (e_18) throw e_18.error; }
10370
10981
  }
10371
10982
  if (candidateField) {
10372
10983
  break;
@@ -10522,7 +11133,7 @@ function buildCompletionFallbackSources(field) {
10522
11133
  ]);
10523
11134
  }
10524
11135
  function resolveAggregateCompletionExprFallback(pipeline) {
10525
- var e_20, _a;
11136
+ var e_19, _a;
10526
11137
  if (!Array.isArray(pipeline)) {
10527
11138
  return null;
10528
11139
  }
@@ -10542,7 +11153,7 @@ function resolveAggregateCompletionExprFallback(pipeline) {
10542
11153
  }
10543
11154
  if (!candidateField) {
10544
11155
  try {
10545
- for (var _b = (e_20 = void 0, __values(Object.keys(matchStage))), _c = _b.next(); !_c.done; _c = _b.next()) {
11156
+ for (var _b = (e_19 = void 0, __values(Object.keys(matchStage))), _c = _b.next(); !_c.done; _c = _b.next()) {
10546
11157
  var key = _c.value;
10547
11158
  if (key.startsWith('$')) {
10548
11159
  continue;
@@ -10557,12 +11168,12 @@ function resolveAggregateCompletionExprFallback(pipeline) {
10557
11168
  }
10558
11169
  }
10559
11170
  }
10560
- catch (e_20_1) { e_20 = { error: e_20_1 }; }
11171
+ catch (e_19_1) { e_19 = { error: e_19_1 }; }
10561
11172
  finally {
10562
11173
  try {
10563
11174
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
10564
11175
  }
10565
- finally { if (e_20) throw e_20.error; }
11176
+ finally { if (e_19) throw e_19.error; }
10566
11177
  }
10567
11178
  }
10568
11179
  if (!candidateField) {
@@ -10641,6 +11252,68 @@ function findAggregateGroupIndex(pipeline) {
10641
11252
  }
10642
11253
  return -1;
10643
11254
  }
11255
+ function doesAssistantAggregateRequireDimension(pipeline) {
11256
+ var _a;
11257
+ var groupIndex = findAggregateGroupIndex(pipeline || []);
11258
+ if (groupIndex === -1) {
11259
+ return false;
11260
+ }
11261
+ var groupStage = pipeline[groupIndex];
11262
+ var groupId = (_a = groupStage === null || groupStage === void 0 ? void 0 : groupStage.$group) === null || _a === void 0 ? void 0 : _a._id;
11263
+ if (groupId === null || groupId === undefined) {
11264
+ return false;
11265
+ }
11266
+ if (typeof groupId === 'object' && !Array.isArray(groupId) && Object.keys(groupId).length === 0) {
11267
+ return false;
11268
+ }
11269
+ return true;
11270
+ }
11271
+ function resolveAssistantAggregateDimensionFieldHints(pipeline) {
11272
+ var groupIndex = findAggregateGroupIndex(pipeline || []);
11273
+ if (groupIndex === -1) {
11274
+ return [];
11275
+ }
11276
+ var hints = [];
11277
+ var pushHint = function (value) {
11278
+ var normalized = normalizeOptionalString(value);
11279
+ if (!normalized || hints.includes(normalized)) {
11280
+ return;
11281
+ }
11282
+ hints.push(normalized);
11283
+ };
11284
+ var _loop_7 = function (index) {
11285
+ var stage = pipeline[index];
11286
+ if (!stage || typeof stage !== 'object' || Array.isArray(stage) || !stage.$project || typeof stage.$project !== 'object') {
11287
+ return "continue";
11288
+ }
11289
+ Object.keys(stage.$project).forEach(function (key) {
11290
+ if (key === '_id') {
11291
+ return;
11292
+ }
11293
+ var expression = stage.$project[key];
11294
+ if (expression === 0 || expression === false) {
11295
+ return;
11296
+ }
11297
+ if (!isAssistantCustomerLabelFieldName(key) && !/(name|label|title|customer|client|account|vendor|location|well|chemical|status|type|group|category)/i.test(key)) {
11298
+ return;
11299
+ }
11300
+ pushHint(formatDisplayColumnName(key) || key);
11301
+ pushHint(key);
11302
+ });
11303
+ };
11304
+ for (var index = groupIndex + 1; index < pipeline.length; index += 1) {
11305
+ _loop_7(index);
11306
+ }
11307
+ return hints.slice(0, 6);
11308
+ }
11309
+ function buildAssistantAggregateFallbackAcceptanceOptions(pipeline) {
11310
+ var requireDimensionFields = doesAssistantAggregateRequireDimension(pipeline || []);
11311
+ return {
11312
+ requireDimensionFields: requireDimensionFields,
11313
+ minDimensionFillRate: requireDimensionFields ? 0.35 : 0.1,
11314
+ preferredDimensionFields: resolveAssistantAggregateDimensionFieldHints(pipeline || [])
11315
+ };
11316
+ }
10644
11317
  function extractGroupFieldPaths(groupStage) {
10645
11318
  if (!groupStage || typeof groupStage !== 'object') {
10646
11319
  return [];
@@ -10702,7 +11375,7 @@ function hasAssistantDateGroupingOperator(value) {
10702
11375
  return Object.keys(value).some(function (key) { return hasAssistantDateGroupingOperator(value[key]); });
10703
11376
  }
10704
11377
  function isGroupFieldDerivedFromDateExpression(pipeline, groupIndex, groupPaths) {
10705
- var e_21, _a, e_22, _b;
11378
+ var e_20, _a, e_21, _b;
10706
11379
  if (!Array.isArray(pipeline) || groupIndex <= 0 || !groupPaths.length) {
10707
11380
  return false;
10708
11381
  }
@@ -10728,14 +11401,14 @@ function isGroupFieldDerivedFromDateExpression(pipeline, groupIndex, groupPaths)
10728
11401
  continue;
10729
11402
  }
10730
11403
  try {
10731
- for (var stageKeys_1 = (e_21 = void 0, __values(stageKeys)), stageKeys_1_1 = stageKeys_1.next(); !stageKeys_1_1.done; stageKeys_1_1 = stageKeys_1.next()) {
11404
+ for (var stageKeys_1 = (e_20 = void 0, __values(stageKeys)), stageKeys_1_1 = stageKeys_1.next(); !stageKeys_1_1.done; stageKeys_1_1 = stageKeys_1.next()) {
10732
11405
  var stageKey = stageKeys_1_1.value;
10733
11406
  var payload = stage[stageKey];
10734
11407
  if (!payload || typeof payload !== 'object' || Array.isArray(payload)) {
10735
11408
  continue;
10736
11409
  }
10737
11410
  try {
10738
- for (var groupFields_1 = (e_22 = void 0, __values(groupFields)), groupFields_1_1 = groupFields_1.next(); !groupFields_1_1.done; groupFields_1_1 = groupFields_1.next()) {
11411
+ for (var groupFields_1 = (e_21 = void 0, __values(groupFields)), groupFields_1_1 = groupFields_1.next(); !groupFields_1_1.done; groupFields_1_1 = groupFields_1.next()) {
10739
11412
  var groupField = groupFields_1_1.value;
10740
11413
  if (!Object.prototype.hasOwnProperty.call(payload, groupField)) {
10741
11414
  continue;
@@ -10745,21 +11418,21 @@ function isGroupFieldDerivedFromDateExpression(pipeline, groupIndex, groupPaths)
10745
11418
  }
10746
11419
  }
10747
11420
  }
10748
- catch (e_22_1) { e_22 = { error: e_22_1 }; }
11421
+ catch (e_21_1) { e_21 = { error: e_21_1 }; }
10749
11422
  finally {
10750
11423
  try {
10751
11424
  if (groupFields_1_1 && !groupFields_1_1.done && (_b = groupFields_1.return)) _b.call(groupFields_1);
10752
11425
  }
10753
- finally { if (e_22) throw e_22.error; }
11426
+ finally { if (e_21) throw e_21.error; }
10754
11427
  }
10755
11428
  }
10756
11429
  }
10757
- catch (e_21_1) { e_21 = { error: e_21_1 }; }
11430
+ catch (e_20_1) { e_20 = { error: e_20_1 }; }
10758
11431
  finally {
10759
11432
  try {
10760
11433
  if (stageKeys_1_1 && !stageKeys_1_1.done && (_a = stageKeys_1.return)) _a.call(stageKeys_1);
10761
11434
  }
10762
- finally { if (e_21) throw e_21.error; }
11435
+ finally { if (e_20) throw e_20.error; }
10763
11436
  }
10764
11437
  }
10765
11438
  return false;
@@ -10866,7 +11539,7 @@ function isRegexMatchCondition(value) {
10866
11539
  return false;
10867
11540
  }
10868
11541
  function findRegexMatchInMatchObject(match, prefix) {
10869
- var e_23, _a, e_24, _b;
11542
+ var e_22, _a, e_23, _b;
10870
11543
  if (prefix === void 0) { prefix = ''; }
10871
11544
  if (Array.isArray(match)) {
10872
11545
  try {
@@ -10878,12 +11551,12 @@ function findRegexMatchInMatchObject(match, prefix) {
10878
11551
  }
10879
11552
  }
10880
11553
  }
10881
- catch (e_23_1) { e_23 = { error: e_23_1 }; }
11554
+ catch (e_22_1) { e_22 = { error: e_22_1 }; }
10882
11555
  finally {
10883
11556
  try {
10884
11557
  if (match_1_1 && !match_1_1.done && (_a = match_1.return)) _a.call(match_1);
10885
11558
  }
10886
- finally { if (e_23) throw e_23.error; }
11559
+ finally { if (e_22) throw e_22.error; }
10887
11560
  }
10888
11561
  return null;
10889
11562
  }
@@ -10914,12 +11587,12 @@ function findRegexMatchInMatchObject(match, prefix) {
10914
11587
  }
10915
11588
  }
10916
11589
  }
10917
- catch (e_24_1) { e_24 = { error: e_24_1 }; }
11590
+ catch (e_23_1) { e_23 = { error: e_23_1 }; }
10918
11591
  finally {
10919
11592
  try {
10920
11593
  if (keys_2_1 && !keys_2_1.done && (_b = keys_2.return)) _b.call(keys_2);
10921
11594
  }
10922
- finally { if (e_24) throw e_24.error; }
11595
+ finally { if (e_23) throw e_23.error; }
10923
11596
  }
10924
11597
  return null;
10925
11598
  }
@@ -11143,7 +11816,7 @@ function collectMatchFieldsByCondition(match, predicate, prefix) {
11143
11816
  return results;
11144
11817
  }
11145
11818
  function findMatchConditionForField(match, targetField, prefix) {
11146
- var e_25, _a, e_26, _b;
11819
+ var e_24, _a, e_25, _b;
11147
11820
  if (prefix === void 0) { prefix = ''; }
11148
11821
  if (!match || typeof match !== 'object') {
11149
11822
  return undefined;
@@ -11158,12 +11831,12 @@ function findMatchConditionForField(match, targetField, prefix) {
11158
11831
  }
11159
11832
  }
11160
11833
  }
11161
- catch (e_25_1) { e_25 = { error: e_25_1 }; }
11834
+ catch (e_24_1) { e_24 = { error: e_24_1 }; }
11162
11835
  finally {
11163
11836
  try {
11164
11837
  if (match_2_1 && !match_2_1.done && (_a = match_2.return)) _a.call(match_2);
11165
11838
  }
11166
- finally { if (e_25) throw e_25.error; }
11839
+ finally { if (e_24) throw e_24.error; }
11167
11840
  }
11168
11841
  return undefined;
11169
11842
  }
@@ -11190,12 +11863,12 @@ function findMatchConditionForField(match, targetField, prefix) {
11190
11863
  }
11191
11864
  }
11192
11865
  }
11193
- catch (e_26_1) { e_26 = { error: e_26_1 }; }
11866
+ catch (e_25_1) { e_25 = { error: e_25_1 }; }
11194
11867
  finally {
11195
11868
  try {
11196
11869
  if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
11197
11870
  }
11198
- finally { if (e_26) throw e_26.error; }
11871
+ finally { if (e_25) throw e_25.error; }
11199
11872
  }
11200
11873
  return undefined;
11201
11874
  }
@@ -11341,7 +12014,7 @@ function detectIdLikeValue(value) {
11341
12014
  return false;
11342
12015
  }
11343
12016
  function detectChemicalIdFromProbe(probeDocs, fields) {
11344
- var e_27, _a, e_28, _b;
12017
+ var e_26, _a, e_27, _b;
11345
12018
  if (!Array.isArray(probeDocs) || !probeDocs.length) {
11346
12019
  return false;
11347
12020
  }
@@ -11353,7 +12026,7 @@ function detectChemicalIdFromProbe(probeDocs, fields) {
11353
12026
  for (var probeDocs_1 = __values(probeDocs), probeDocs_1_1 = probeDocs_1.next(); !probeDocs_1_1.done; probeDocs_1_1 = probeDocs_1.next()) {
11354
12027
  var doc = probeDocs_1_1.value;
11355
12028
  try {
11356
- for (var targets_1 = (e_28 = void 0, __values(targets)), targets_1_1 = targets_1.next(); !targets_1_1.done; targets_1_1 = targets_1.next()) {
12029
+ for (var targets_1 = (e_27 = void 0, __values(targets)), targets_1_1 = targets_1.next(); !targets_1_1.done; targets_1_1 = targets_1.next()) {
11357
12030
  var field = targets_1_1.value;
11358
12031
  var value = getValueAtPath(doc, field);
11359
12032
  if (Array.isArray(value)) {
@@ -11366,21 +12039,21 @@ function detectChemicalIdFromProbe(probeDocs, fields) {
11366
12039
  }
11367
12040
  }
11368
12041
  }
11369
- catch (e_28_1) { e_28 = { error: e_28_1 }; }
12042
+ catch (e_27_1) { e_27 = { error: e_27_1 }; }
11370
12043
  finally {
11371
12044
  try {
11372
12045
  if (targets_1_1 && !targets_1_1.done && (_b = targets_1.return)) _b.call(targets_1);
11373
12046
  }
11374
- finally { if (e_28) throw e_28.error; }
12047
+ finally { if (e_27) throw e_27.error; }
11375
12048
  }
11376
12049
  }
11377
12050
  }
11378
- catch (e_27_1) { e_27 = { error: e_27_1 }; }
12051
+ catch (e_26_1) { e_26 = { error: e_26_1 }; }
11379
12052
  finally {
11380
12053
  try {
11381
12054
  if (probeDocs_1_1 && !probeDocs_1_1.done && (_a = probeDocs_1.return)) _a.call(probeDocs_1);
11382
12055
  }
11383
- finally { if (e_27) throw e_27.error; }
12056
+ finally { if (e_26) throw e_26.error; }
11384
12057
  }
11385
12058
  return false;
11386
12059
  }
@@ -11601,8 +12274,8 @@ function buildChemicalIdFieldCandidates(field) {
11601
12274
  }
11602
12275
  function applyChemicalNameLookupFallbackToQuery(params) {
11603
12276
  return __awaiter(this, void 0, void 0, function () {
11604
- var query, db, dbName, idClient, idCustomer, isSuperAdmin, probeDocs, chemicalFields, targetField, condition, regex, sampleDocs, collectionNames, candidates, _loop_7, candidates_2, candidates_2_1, candidate, state_5, e_29_1;
11605
- var e_29, _a;
12277
+ var query, db, dbName, idClient, idCustomer, isSuperAdmin, probeDocs, chemicalFields, targetField, condition, regex, sampleDocs, collectionNames, candidates, _loop_8, candidates_1, candidates_1_1, candidate, state_5, e_28_1;
12278
+ var e_28, _a;
11606
12279
  var _b;
11607
12280
  return __generator(this, function (_c) {
11608
12281
  switch (_c.label) {
@@ -11626,7 +12299,7 @@ function applyChemicalNameLookupFallbackToQuery(params) {
11626
12299
  case 1:
11627
12300
  collectionNames = _c.sent();
11628
12301
  candidates = resolveIdLookupCandidates('chemical', collectionNames);
11629
- _loop_7 = function (candidate) {
12302
+ _loop_8 = function (candidate) {
11630
12303
  var candidateHasClientScope, _d, candidateProbe, lookup, idFields, baseMatch, orConditions, nextMatch;
11631
12304
  return __generator(this, function (_e) {
11632
12305
  switch (_e.label) {
@@ -11699,30 +12372,30 @@ function applyChemicalNameLookupFallbackToQuery(params) {
11699
12372
  _c.label = 2;
11700
12373
  case 2:
11701
12374
  _c.trys.push([2, 7, 8, 9]);
11702
- candidates_2 = __values(candidates), candidates_2_1 = candidates_2.next();
12375
+ candidates_1 = __values(candidates), candidates_1_1 = candidates_1.next();
11703
12376
  _c.label = 3;
11704
12377
  case 3:
11705
- if (!!candidates_2_1.done) return [3 /*break*/, 6];
11706
- candidate = candidates_2_1.value;
11707
- return [5 /*yield**/, _loop_7(candidate)];
12378
+ if (!!candidates_1_1.done) return [3 /*break*/, 6];
12379
+ candidate = candidates_1_1.value;
12380
+ return [5 /*yield**/, _loop_8(candidate)];
11708
12381
  case 4:
11709
12382
  state_5 = _c.sent();
11710
12383
  if (typeof state_5 === "object")
11711
12384
  return [2 /*return*/, state_5.value];
11712
12385
  _c.label = 5;
11713
12386
  case 5:
11714
- candidates_2_1 = candidates_2.next();
12387
+ candidates_1_1 = candidates_1.next();
11715
12388
  return [3 /*break*/, 3];
11716
12389
  case 6: return [3 /*break*/, 9];
11717
12390
  case 7:
11718
- e_29_1 = _c.sent();
11719
- e_29 = { error: e_29_1 };
12391
+ e_28_1 = _c.sent();
12392
+ e_28 = { error: e_28_1 };
11720
12393
  return [3 /*break*/, 9];
11721
12394
  case 8:
11722
12395
  try {
11723
- if (candidates_2_1 && !candidates_2_1.done && (_a = candidates_2.return)) _a.call(candidates_2);
12396
+ if (candidates_1_1 && !candidates_1_1.done && (_a = candidates_1.return)) _a.call(candidates_1);
11724
12397
  }
11725
- finally { if (e_29) throw e_29.error; }
12398
+ finally { if (e_28) throw e_28.error; }
11726
12399
  return [7 /*endfinally*/];
11727
12400
  case 9: return [2 /*return*/, null];
11728
12401
  }
@@ -11816,8 +12489,8 @@ function lookupIdsForNameMatch(params) {
11816
12489
  }
11817
12490
  function applyIdLookupFallbackToQuery(params) {
11818
12491
  return __awaiter(this, void 0, void 0, function () {
11819
- var query, db, dbName, idClient, idCustomer, isSuperAdmin, probeDocs, conditions, collectionNames, _a, conditions_1, conditions_1_1, condition, regex, baseToken, targetFieldType, nextValue, localNameField, candidates, candidates_3, candidates_3_1, candidate, candidateHasClientScope, _b, candidateProbe, lookup, targetFieldType, normalizedIds, idsForQuery, e_30_1, e_31_1;
11820
- var e_31, _c, e_30, _d;
12492
+ var query, db, dbName, idClient, idCustomer, isSuperAdmin, probeDocs, conditions, collectionNames, _a, conditions_1, conditions_1_1, condition, regex, baseToken, targetFieldType, nextValue, localNameField, candidates, candidates_2, candidates_2_1, candidate, candidateHasClientScope, _b, candidateProbe, lookup, targetFieldType, normalizedIds, idsForQuery, e_29_1, e_30_1;
12493
+ var e_30, _c, e_29, _d;
11821
12494
  var _e;
11822
12495
  return __generator(this, function (_f) {
11823
12496
  switch (_f.label) {
@@ -11887,11 +12560,11 @@ function applyIdLookupFallbackToQuery(params) {
11887
12560
  _f.label = 5;
11888
12561
  case 5:
11889
12562
  _f.trys.push([5, 14, 15, 16]);
11890
- candidates_3 = (e_30 = void 0, __values(candidates)), candidates_3_1 = candidates_3.next();
12563
+ candidates_2 = (e_29 = void 0, __values(candidates)), candidates_2_1 = candidates_2.next();
11891
12564
  _f.label = 6;
11892
12565
  case 6:
11893
- if (!!candidates_3_1.done) return [3 /*break*/, 13];
11894
- candidate = candidates_3_1.value;
12566
+ if (!!candidates_2_1.done) return [3 /*break*/, 13];
12567
+ candidate = candidates_2_1.value;
11895
12568
  if (!candidate) {
11896
12569
  return [3 /*break*/, 12];
11897
12570
  }
@@ -11950,32 +12623,32 @@ function applyIdLookupFallbackToQuery(params) {
11950
12623
  }
11951
12624
  _f.label = 12;
11952
12625
  case 12:
11953
- candidates_3_1 = candidates_3.next();
12626
+ candidates_2_1 = candidates_2.next();
11954
12627
  return [3 /*break*/, 6];
11955
12628
  case 13: return [3 /*break*/, 16];
11956
12629
  case 14:
11957
- e_30_1 = _f.sent();
11958
- e_30 = { error: e_30_1 };
12630
+ e_29_1 = _f.sent();
12631
+ e_29 = { error: e_29_1 };
11959
12632
  return [3 /*break*/, 16];
11960
12633
  case 15:
11961
12634
  try {
11962
- if (candidates_3_1 && !candidates_3_1.done && (_d = candidates_3.return)) _d.call(candidates_3);
12635
+ if (candidates_2_1 && !candidates_2_1.done && (_d = candidates_2.return)) _d.call(candidates_2);
11963
12636
  }
11964
- finally { if (e_30) throw e_30.error; }
12637
+ finally { if (e_29) throw e_29.error; }
11965
12638
  return [7 /*endfinally*/];
11966
12639
  case 16:
11967
12640
  conditions_1_1 = conditions_1.next();
11968
12641
  return [3 /*break*/, 4];
11969
12642
  case 17: return [3 /*break*/, 20];
11970
12643
  case 18:
11971
- e_31_1 = _f.sent();
11972
- e_31 = { error: e_31_1 };
12644
+ e_30_1 = _f.sent();
12645
+ e_30 = { error: e_30_1 };
11973
12646
  return [3 /*break*/, 20];
11974
12647
  case 19:
11975
12648
  try {
11976
12649
  if (conditions_1_1 && !conditions_1_1.done && (_c = conditions_1.return)) _c.call(conditions_1);
11977
12650
  }
11978
- finally { if (e_31) throw e_31.error; }
12651
+ finally { if (e_30) throw e_30.error; }
11979
12652
  return [7 /*endfinally*/];
11980
12653
  case 20: return [2 /*return*/, null];
11981
12654
  }
@@ -12378,27 +13051,255 @@ function listAssistantReportBuilderCollectionsFromManager() {
12378
13051
  });
12379
13052
  return names;
12380
13053
  }
12381
- function listAssistantCollections(db, dbName) {
13054
+ function resolveAssistantSurfaceFileCandidates(baseName) {
13055
+ var fileNames = ["".concat(baseName, ".ts"), "".concat(baseName, ".js")];
13056
+ var roots = [
13057
+ normalizeOptionalString(process.cwd()),
13058
+ normalizeOptionalString(path.resolve(process.cwd(), 'resolveio-server-lib')),
13059
+ normalizeOptionalString(path.resolve(__dirname, '..', '..', '..', '..')),
13060
+ normalizeOptionalString(path.resolve(__dirname, '..', '..', '..')),
13061
+ normalizeOptionalString(path.resolve(__dirname, '..', '..')),
13062
+ normalizeOptionalString(path.resolve(__dirname, '..'))
13063
+ ].filter(Boolean);
13064
+ var candidates = [];
13065
+ roots.forEach(function (root) {
13066
+ fileNames.forEach(function (fileName) {
13067
+ candidates.push(path.resolve(root, fileName));
13068
+ });
13069
+ });
13070
+ return Array.from(new Set(candidates.map(function (value) { return normalizeOptionalString(value); }).filter(Boolean)));
13071
+ }
13072
+ function readFirstAssistantSurfaceFile(candidates) {
12382
13073
  return __awaiter(this, void 0, void 0, function () {
12383
- var cacheKey, cached, now, seen, merged, pushName, collections, _a, names;
13074
+ var candidates_3, candidates_3_1, candidate, normalized, _a, e_31_1;
13075
+ var e_31, _b;
13076
+ return __generator(this, function (_c) {
13077
+ switch (_c.label) {
13078
+ case 0:
13079
+ _c.trys.push([0, 7, 8, 9]);
13080
+ candidates_3 = __values(candidates), candidates_3_1 = candidates_3.next();
13081
+ _c.label = 1;
13082
+ case 1:
13083
+ if (!!candidates_3_1.done) return [3 /*break*/, 6];
13084
+ candidate = candidates_3_1.value;
13085
+ normalized = normalizeOptionalString(candidate);
13086
+ if (!normalized) {
13087
+ return [3 /*break*/, 5];
13088
+ }
13089
+ _c.label = 2;
13090
+ case 2:
13091
+ _c.trys.push([2, 4, , 5]);
13092
+ return [4 /*yield*/, fs_1.promises.readFile(normalized, 'utf8')];
13093
+ case 3: return [2 /*return*/, _c.sent()];
13094
+ case 4:
13095
+ _a = _c.sent();
13096
+ return [3 /*break*/, 5];
13097
+ case 5:
13098
+ candidates_3_1 = candidates_3.next();
13099
+ return [3 /*break*/, 1];
13100
+ case 6: return [3 /*break*/, 9];
13101
+ case 7:
13102
+ e_31_1 = _c.sent();
13103
+ e_31 = { error: e_31_1 };
13104
+ return [3 /*break*/, 9];
13105
+ case 8:
13106
+ try {
13107
+ if (candidates_3_1 && !candidates_3_1.done && (_b = candidates_3.return)) _b.call(candidates_3);
13108
+ }
13109
+ finally { if (e_31) throw e_31.error; }
13110
+ return [7 /*endfinally*/];
13111
+ case 9: return [2 /*return*/, ''];
13112
+ }
13113
+ });
13114
+ });
13115
+ }
13116
+ function extractAssistantSurfaceNamesFromFile(source) {
13117
+ var text = normalizeOptionalString(source);
13118
+ if (!text) {
13119
+ return [];
13120
+ }
13121
+ var names = [];
13122
+ var seen = new Set();
13123
+ var keyPattern = /^\s*([A-Za-z_$][A-Za-z0-9_$]*)\s*:\s*\(/gm;
13124
+ var match = keyPattern.exec(text);
13125
+ while (match) {
13126
+ var key = normalizeOptionalString(match[1]);
13127
+ if (key && !seen.has(key)) {
13128
+ seen.add(key);
13129
+ names.push(key);
13130
+ }
13131
+ match = keyPattern.exec(text);
13132
+ }
13133
+ return names;
13134
+ }
13135
+ function loadAssistantSurfaceIndex() {
13136
+ return __awaiter(this, void 0, void 0, function () {
13137
+ var now, _a, methodsSource, publicationsSource, methods, publications, index;
12384
13138
  return __generator(this, function (_b) {
12385
13139
  switch (_b.label) {
12386
13140
  case 0:
12387
- cacheKey = normalizeOptionalString(dbName) || 'default';
12388
- cached = AI_ASSISTANT_COLLECTION_CACHE.get(cacheKey);
12389
13141
  now = Date.now();
12390
- if (cached && now - cached.updatedAt < AI_ASSISTANT_COLLECTION_CACHE_TTL_MS) {
12391
- return [2 /*return*/, cached.names];
13142
+ if (cachedAssistantSurfaceIndex
13143
+ && now - cachedAssistantSurfaceIndex.updatedAt < AI_ASSISTANT_SURFACE_INDEX_CACHE_TTL_MS) {
13144
+ return [2 /*return*/, cachedAssistantSurfaceIndex];
12392
13145
  }
12393
- seen = new Set();
12394
- merged = [];
12395
- pushName = function (name) {
12396
- var normalized = normalizeOptionalString(name);
12397
- if (!normalized || seen.has(normalized)) {
12398
- return;
12399
- }
12400
- seen.add(normalized);
12401
- merged.push(normalized);
13146
+ return [4 /*yield*/, Promise.all([
13147
+ readFirstAssistantSurfaceFile(resolveAssistantSurfaceFileCandidates('methods')),
13148
+ readFirstAssistantSurfaceFile(resolveAssistantSurfaceFileCandidates('publications'))
13149
+ ])];
13150
+ case 1:
13151
+ _a = __read.apply(void 0, [_b.sent(), 2]), methodsSource = _a[0], publicationsSource = _a[1];
13152
+ methods = extractAssistantSurfaceNamesFromFile(methodsSource);
13153
+ publications = extractAssistantSurfaceNamesFromFile(publicationsSource);
13154
+ index = {
13155
+ methods: methods,
13156
+ publications: publications,
13157
+ updatedAt: now
13158
+ };
13159
+ cachedAssistantSurfaceIndex = index;
13160
+ return [2 /*return*/, index];
13161
+ }
13162
+ });
13163
+ });
13164
+ }
13165
+ function tokenizeAssistantSurfaceName(name) {
13166
+ var normalized = normalizeOptionalString(name);
13167
+ if (!normalized) {
13168
+ return [];
13169
+ }
13170
+ return mergeAssistantHintValues(tokenizeCollectionText(normalized), tokenizeFieldKey(normalized).flatMap(function (token) { return normalizeCollectionToken(token); }));
13171
+ }
13172
+ function scoreAssistantSurfaceName(messageTokens, surfaceName) {
13173
+ var requestTokens = Array.isArray(messageTokens) ? messageTokens.filter(Boolean) : [];
13174
+ var normalizedSurface = normalizeOptionalString(surfaceName);
13175
+ if (!requestTokens.length || !normalizedSurface) {
13176
+ return 0;
13177
+ }
13178
+ var surfaceTokens = tokenizeAssistantSurfaceName(normalizedSurface);
13179
+ if (!surfaceTokens.length) {
13180
+ return 0;
13181
+ }
13182
+ var score = 0;
13183
+ requestTokens.forEach(function (token) {
13184
+ if (surfaceTokens.includes(token)) {
13185
+ score += 10;
13186
+ return;
13187
+ }
13188
+ if (surfaceTokens.some(function (surfaceToken) { return surfaceToken.startsWith(token) || token.startsWith(surfaceToken); })) {
13189
+ score += 4;
13190
+ }
13191
+ });
13192
+ var messageKey = normalizeCollectionKey(requestTokens.join(' '));
13193
+ var surfaceKey = normalizeCollectionKey(normalizedSurface);
13194
+ if (messageKey && surfaceKey.includes(messageKey)) {
13195
+ score += 18;
13196
+ }
13197
+ else if (messageKey && messageKey.includes(surfaceKey) && surfaceKey.length >= 5) {
13198
+ score += 8;
13199
+ }
13200
+ return score;
13201
+ }
13202
+ function rankAssistantSurfaceNames(queryText, names, limit) {
13203
+ if (limit === void 0) { limit = AI_ASSISTANT_SURFACE_INDEX_MATCH_LIMIT; }
13204
+ var tokens = mergeAssistantHintValues(tokenizeCollectionText(queryText), tokenizeFieldKey(queryText).flatMap(function (token) { return normalizeCollectionToken(token); }));
13205
+ if (!tokens.length || !Array.isArray(names) || !names.length || limit <= 0) {
13206
+ return [];
13207
+ }
13208
+ return names
13209
+ .map(function (name) { return ({
13210
+ name: name,
13211
+ score: scoreAssistantSurfaceName(tokens, name)
13212
+ }); })
13213
+ .filter(function (entry) { return entry.score > 0; })
13214
+ .sort(function (a, b) {
13215
+ if (a.score !== b.score) {
13216
+ return b.score - a.score;
13217
+ }
13218
+ if (a.name.length !== b.name.length) {
13219
+ return a.name.length - b.name.length;
13220
+ }
13221
+ return a.name.localeCompare(b.name);
13222
+ })
13223
+ .slice(0, limit)
13224
+ .map(function (entry) { return entry.name; });
13225
+ }
13226
+ function resolveAssistantCollectionHintsFromSurfaceNames(surfaceNames, collectionNames) {
13227
+ if (!Array.isArray(surfaceNames) || !surfaceNames.length || !Array.isArray(collectionNames) || !collectionNames.length) {
13228
+ return [];
13229
+ }
13230
+ var hints = [];
13231
+ surfaceNames.forEach(function (surfaceName) {
13232
+ var tokens = tokenizeAssistantSurfaceName(surfaceName);
13233
+ if (!tokens.length) {
13234
+ return;
13235
+ }
13236
+ var tokenHints = resolveCollectionHintsFromTokens(tokens, collectionNames, 2);
13237
+ tokenHints.forEach(function (hint) {
13238
+ if (!hints.includes(hint)) {
13239
+ hints.push(hint);
13240
+ }
13241
+ });
13242
+ tokens.forEach(function (token) {
13243
+ var aliasCandidates = resolveAssistantBridgeCollectionAliasCandidates(token);
13244
+ aliasCandidates.forEach(function (aliasCandidate) {
13245
+ if (collectionNames.includes(aliasCandidate) && !hints.includes(aliasCandidate)) {
13246
+ hints.push(aliasCandidate);
13247
+ }
13248
+ });
13249
+ });
13250
+ });
13251
+ return hints.slice(0, AI_ASSISTANT_SURFACE_INDEX_COLLECTION_HINT_LIMIT);
13252
+ }
13253
+ function resolveAssistantSurfaceHints(message, contextRoute, collectionNames) {
13254
+ return __awaiter(this, void 0, void 0, function () {
13255
+ var queryText, surfaceIndex, methodHints, publicationHints, collectionHints;
13256
+ return __generator(this, function (_a) {
13257
+ switch (_a.label) {
13258
+ case 0:
13259
+ queryText = [message, contextRoute].filter(Boolean).join(' ');
13260
+ if (!normalizeOptionalString(queryText) || !Array.isArray(collectionNames) || !collectionNames.length) {
13261
+ return [2 /*return*/, {
13262
+ collectionHints: [],
13263
+ methodHints: [],
13264
+ publicationHints: []
13265
+ }];
13266
+ }
13267
+ return [4 /*yield*/, loadAssistantSurfaceIndex()];
13268
+ case 1:
13269
+ surfaceIndex = _a.sent();
13270
+ methodHints = rankAssistantSurfaceNames(queryText, surfaceIndex.methods, AI_ASSISTANT_SURFACE_INDEX_MATCH_LIMIT);
13271
+ publicationHints = rankAssistantSurfaceNames(queryText, surfaceIndex.publications, AI_ASSISTANT_SURFACE_INDEX_MATCH_LIMIT);
13272
+ collectionHints = resolveAssistantCollectionHintsFromSurfaceNames(mergeAssistantHintValues(methodHints, publicationHints), collectionNames);
13273
+ return [2 /*return*/, {
13274
+ collectionHints: collectionHints,
13275
+ methodHints: methodHints,
13276
+ publicationHints: publicationHints
13277
+ }];
13278
+ }
13279
+ });
13280
+ });
13281
+ }
13282
+ function listAssistantCollections(db, dbName) {
13283
+ return __awaiter(this, void 0, void 0, function () {
13284
+ var cacheKey, cached, now, seen, merged, pushName, collections, _a, names;
13285
+ return __generator(this, function (_b) {
13286
+ switch (_b.label) {
13287
+ case 0:
13288
+ cacheKey = normalizeOptionalString(dbName) || 'default';
13289
+ cached = AI_ASSISTANT_COLLECTION_CACHE.get(cacheKey);
13290
+ now = Date.now();
13291
+ if (cached && now - cached.updatedAt < AI_ASSISTANT_COLLECTION_CACHE_TTL_MS) {
13292
+ return [2 /*return*/, cached.names];
13293
+ }
13294
+ seen = new Set();
13295
+ merged = [];
13296
+ pushName = function (name) {
13297
+ var normalized = normalizeOptionalString(name);
13298
+ if (!normalized || seen.has(normalized)) {
13299
+ return;
13300
+ }
13301
+ seen.add(normalized);
13302
+ merged.push(normalized);
12402
13303
  };
12403
13304
  listAssistantReportBuilderCollectionsFromManager().forEach(pushName);
12404
13305
  _b.label = 1;
@@ -12502,6 +13403,164 @@ function resolveCollectionHintsFromTokens(tokens, collectionNames, max) {
12502
13403
  .slice(0, Math.max(max, 0))
12503
13404
  .map(function (entry) { return entry.name; });
12504
13405
  }
13406
+ function resolveCollectionHintsFromRanking(collectionRanking, max) {
13407
+ if (max === void 0) { max = 5; }
13408
+ var ranked = Array.isArray(collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked) ? collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked : [];
13409
+ if (!ranked.length || max <= 0) {
13410
+ return [];
13411
+ }
13412
+ return ranked
13413
+ .map(function (entry) { return normalizeOptionalString(entry === null || entry === void 0 ? void 0 : entry.name); })
13414
+ .filter(Boolean)
13415
+ .slice(0, max);
13416
+ }
13417
+ function buildAssistantCollectionProfile(collectionName) {
13418
+ var normalized = normalizeOptionalString(collectionName);
13419
+ if (!normalized) {
13420
+ return {
13421
+ nameTokens: [],
13422
+ fieldTokens: [],
13423
+ lookupFamilyTokens: [],
13424
+ idBaseTokens: []
13425
+ };
13426
+ }
13427
+ var now = Date.now();
13428
+ var cached = AI_ASSISTANT_COLLECTION_PROFILE_CACHE.get(normalized);
13429
+ if (cached && now - cached.updatedAt < AI_ASSISTANT_COLLECTION_PROFILE_CACHE_TTL_MS) {
13430
+ return cached.profile;
13431
+ }
13432
+ var metadata = getAssistantCollectionMetadata(normalized);
13433
+ var fieldTokenCounts = new Map();
13434
+ var idBaseTokens = new Set();
13435
+ (metadata.fields || []).forEach(function (fieldPath) {
13436
+ var normalizedPath = normalizeLookupPath(fieldPath);
13437
+ if (!normalizedPath) {
13438
+ return;
13439
+ }
13440
+ var tokens = mergeAssistantHintValues(tokenizeFieldKey(normalizedPath).flatMap(function (token) { return normalizeCollectionToken(token); }), tokenizeCollectionText(normalizedPath));
13441
+ tokens.forEach(function (token) {
13442
+ if (!token) {
13443
+ return;
13444
+ }
13445
+ fieldTokenCounts.set(token, (fieldTokenCounts.get(token) || 0) + 1);
13446
+ });
13447
+ var leaf = normalizedPath.split('.').pop() || normalizedPath;
13448
+ if (/^id_[a-z0-9_]+$/i.test(leaf)) {
13449
+ var token = normalizeOptionalString(leaf.slice(3)).toLowerCase();
13450
+ if (token) {
13451
+ idBaseTokens.add(token);
13452
+ fieldTokenCounts.set(token, (fieldTokenCounts.get(token) || 0) + 2);
13453
+ }
13454
+ }
13455
+ });
13456
+ var fieldTokens = Array.from(fieldTokenCounts.entries())
13457
+ .sort(function (a, b) {
13458
+ if (a[1] !== b[1]) {
13459
+ return b[1] - a[1];
13460
+ }
13461
+ return a[0].localeCompare(b[0]);
13462
+ })
13463
+ .slice(0, AI_ASSISTANT_COLLECTION_PROFILE_FIELD_TOKEN_LIMIT)
13464
+ .map(function (entry) { return entry[0]; });
13465
+ var lookupFamilyTokens = mergeAssistantHintValues((metadata.lookups || [])
13466
+ .map(function (mapping) { return normalizeAssistantCollectionFamilyName(mapping.lookupCollection); })
13467
+ .filter(Boolean)
13468
+ .flatMap(function (family) { return mergeAssistantHintValues([family], tokenizeCollectionText(family), family.split(/[^a-z0-9]+/g).filter(Boolean)); }));
13469
+ var profile = {
13470
+ nameTokens: tokenizeCollectionText(normalized),
13471
+ fieldTokens: fieldTokens,
13472
+ lookupFamilyTokens: lookupFamilyTokens,
13473
+ idBaseTokens: Array.from(idBaseTokens)
13474
+ };
13475
+ AI_ASSISTANT_COLLECTION_PROFILE_CACHE.set(normalized, {
13476
+ profile: profile,
13477
+ updatedAt: now
13478
+ });
13479
+ return profile;
13480
+ }
13481
+ function buildCollectionRankingDebugFromSignals(tokens, collectionNames, signals, max) {
13482
+ if (max === void 0) { max = 8; }
13483
+ var requestedTokens = Array.from(new Set(mergeAssistantHintValues(tokens || [], (signals === null || signals === void 0 ? void 0 : signals.requestedTokens) || [])));
13484
+ var requestedKey = normalizeCollectionKey(requestedTokens.join('-'));
13485
+ var _a = computeCollectionTokenWeights(requestedTokens), weights = _a.weights, hasDomain = _a.hasDomain;
13486
+ var methodTokens = mergeAssistantHintValues.apply(void 0, __spreadArray([], __read((Array.isArray(signals === null || signals === void 0 ? void 0 : signals.methodHints) ? signals === null || signals === void 0 ? void 0 : signals.methodHints : [])
13487
+ .map(function (name) { return tokenizeAssistantSurfaceName(name); })), false));
13488
+ var publicationTokens = mergeAssistantHintValues.apply(void 0, __spreadArray([], __read((Array.isArray(signals === null || signals === void 0 ? void 0 : signals.publicationHints) ? signals === null || signals === void 0 ? void 0 : signals.publicationHints : [])
13489
+ .map(function (name) { return tokenizeAssistantSurfaceName(name); })), false));
13490
+ var routeTokens = mergeAssistantHintValues.apply(void 0, __spreadArray([], __read((Array.isArray(signals === null || signals === void 0 ? void 0 : signals.routeHints) ? signals === null || signals === void 0 ? void 0 : signals.routeHints : [])
13491
+ .map(function (route) { return tokenizeCollectionText(route); })), false));
13492
+ var boostedNames = new Set((Array.isArray(signals === null || signals === void 0 ? void 0 : signals.boostedCollections) ? signals === null || signals === void 0 ? void 0 : signals.boostedCollections : [])
13493
+ .map(function (value) { return normalizeOptionalString(value); })
13494
+ .filter(Boolean));
13495
+ var boostedFamilies = new Set(Array.from(boostedNames)
13496
+ .map(function (value) { return normalizeAssistantCollectionFamilyName(value); })
13497
+ .filter(Boolean));
13498
+ if (!requestedTokens.length || !collectionNames.length) {
13499
+ return {
13500
+ tokens: requestedTokens,
13501
+ requestedKey: requestedKey,
13502
+ hasDomain: hasDomain,
13503
+ tokenWeights: weights,
13504
+ rankingMode: 'qualified',
13505
+ ranked: []
13506
+ };
13507
+ }
13508
+ var surfaceTokens = mergeAssistantHintValues(methodTokens, publicationTokens);
13509
+ var ranked = collectionNames
13510
+ .map(function (name) {
13511
+ var base = scoreCollectionMatchDetailed(requestedTokens, name, weights);
13512
+ var profile = buildAssistantCollectionProfile(name);
13513
+ var profileTokenPool = new Set(__spreadArray(__spreadArray(__spreadArray(__spreadArray([], __read(profile.nameTokens), false), __read(profile.fieldTokens), false), __read(profile.lookupFamilyTokens), false), __read(profile.idBaseTokens), false));
13514
+ var profileTokenMatches = requestedTokens.filter(function (token) { return profileTokenPool.has(token); });
13515
+ var lookupMatches = requestedTokens.filter(function (token) { return profile.lookupFamilyTokens.includes(token); });
13516
+ var surfaceMatches = surfaceTokens.filter(function (token) { return profileTokenPool.has(token); });
13517
+ var routeMatches = routeTokens.filter(function (token) { return profile.nameTokens.includes(token) || profile.fieldTokens.includes(token); });
13518
+ var family = normalizeAssistantCollectionFamilyName(name);
13519
+ var boosted = boostedNames.has(name) || (family ? boostedFamilies.has(family) : false);
13520
+ var signalScore = (profileTokenMatches.length * 3)
13521
+ + (lookupMatches.length * 4)
13522
+ + (surfaceMatches.length * 2)
13523
+ + (routeMatches.length * 3)
13524
+ + (boosted ? 14 : 0);
13525
+ return {
13526
+ name: name,
13527
+ score: base.score + signalScore,
13528
+ baseScore: base.score,
13529
+ signalScore: signalScore,
13530
+ tokenMatches: base.tokenMatches,
13531
+ keyMatch: base.keyMatch,
13532
+ candidateTokens: base.candidateTokens,
13533
+ tokenScore: base.tokenScore,
13534
+ tokenWeights: base.tokenWeights,
13535
+ signal: {
13536
+ profileMatches: profileTokenMatches.slice(0, 8),
13537
+ lookupMatches: lookupMatches.slice(0, 6),
13538
+ surfaceMatches: surfaceMatches.slice(0, 6),
13539
+ routeMatches: routeMatches.slice(0, 6),
13540
+ boosted: boosted
13541
+ }
13542
+ };
13543
+ })
13544
+ .filter(function (entry) { return entry.score > 0; })
13545
+ .sort(function (a, b) {
13546
+ if (a.score !== b.score) {
13547
+ return b.score - a.score;
13548
+ }
13549
+ if (a.baseScore !== b.baseScore) {
13550
+ return b.baseScore - a.baseScore;
13551
+ }
13552
+ return a.name.localeCompare(b.name);
13553
+ })
13554
+ .slice(0, Math.max(max, 0));
13555
+ return {
13556
+ tokens: requestedTokens,
13557
+ requestedKey: requestedKey,
13558
+ hasDomain: hasDomain,
13559
+ tokenWeights: weights,
13560
+ rankingMode: 'qualified',
13561
+ ranked: ranked
13562
+ };
13563
+ }
12505
13564
  function mergeAssistantHintValues() {
12506
13565
  var groups = [];
12507
13566
  for (var _i = 0; _i < arguments.length; _i++) {
@@ -12559,6 +13618,13 @@ function hasAssistantChemicalCatalogAliasTerms(value) {
12559
13618
  }
12560
13619
  return /\b(chemicals?|products?|items?)\b/i.test(normalized);
12561
13620
  }
13621
+ function hasAssistantWorkOrderAliasTerms(value) {
13622
+ var normalized = normalizeOptionalString(value).toLowerCase();
13623
+ if (!normalized) {
13624
+ return false;
13625
+ }
13626
+ return /\bwork[\s_-]*orders?\b/i.test(normalized);
13627
+ }
12562
13628
  var AI_ASSISTANT_DELIVERY_HINT_CANDIDATES = [
12563
13629
  'work-order-dynamics',
12564
13630
  'work-orders',
@@ -12580,6 +13646,13 @@ var AI_ASSISTANT_CHEMICAL_HINT_CANDIDATES = [
12580
13646
  'inventory',
12581
13647
  'blends'
12582
13648
  ];
13649
+ var AI_ASSISTANT_WORK_ORDER_HINT_CANDIDATES = [
13650
+ 'work-order-dynamics',
13651
+ 'work-orders',
13652
+ 'maintenance-orders',
13653
+ 'repair-orders',
13654
+ 'orders'
13655
+ ];
12583
13656
  function resolveCollectionHintsFromRoute(route, collectionNames) {
12584
13657
  var normalizedRoute = normalizeOptionalString(route);
12585
13658
  if (!normalizedRoute || !collectionNames.length) {
@@ -12611,6 +13684,12 @@ function resolveCollectionHintsFromRoute(route, collectionNames) {
12611
13684
  });
12612
13685
  return mergeAssistantHintValues(hints);
12613
13686
  }
13687
+ function resolveCollectionHintsFromRoutes(routes, collectionNames) {
13688
+ if (!Array.isArray(routes) || !routes.length || !Array.isArray(collectionNames) || !collectionNames.length) {
13689
+ return [];
13690
+ }
13691
+ return mergeAssistantHintValues.apply(void 0, __spreadArray([], __read(routes.map(function (route) { return resolveCollectionHintsFromRoute(route, collectionNames); })), false));
13692
+ }
12614
13693
  function resolveAssistantDefaultCollectionHints(message) {
12615
13694
  var text = normalizeOptionalString(message).toLowerCase();
12616
13695
  if (!text) {
@@ -12637,6 +13716,9 @@ function resolveAssistantDefaultCollectionHints(message) {
12637
13716
  if (hasAssistantChemicalCatalogAliasTerms(text)) {
12638
13717
  AI_ASSISTANT_CHEMICAL_HINT_CANDIDATES.forEach(push);
12639
13718
  }
13719
+ if (hasAssistantWorkOrderAliasTerms(text)) {
13720
+ AI_ASSISTANT_WORK_ORDER_HINT_CANDIDATES.forEach(push);
13721
+ }
12640
13722
  return hints;
12641
13723
  }
12642
13724
  function buildCollectionRankingDebugFromTokens(tokens, collectionNames, max) {
@@ -13151,6 +14233,155 @@ function buildAssistantRetryState(baseState, triedCollections, options) {
13151
14233
  }
13152
14234
  return next;
13153
14235
  }
14236
+ function addAssistantCollectionRelationshipEdge(graph, fromFamily, toFamily, weight) {
14237
+ var from = normalizeAssistantCollectionFamilyName(fromFamily);
14238
+ var to = normalizeAssistantCollectionFamilyName(toFamily);
14239
+ if (!from || !to || from === to || !Number.isFinite(weight) || weight <= 0) {
14240
+ return;
14241
+ }
14242
+ var neighbors = graph.get(from);
14243
+ if (!neighbors) {
14244
+ neighbors = new Map();
14245
+ graph.set(from, neighbors);
14246
+ }
14247
+ neighbors.set(to, (neighbors.get(to) || 0) + weight);
14248
+ }
14249
+ function buildAssistantCollectionGraphSignature(collectionNames) {
14250
+ if (!Array.isArray(collectionNames) || !collectionNames.length) {
14251
+ return '';
14252
+ }
14253
+ var normalized = collectionNames
14254
+ .map(function (name) { return normalizeOptionalString(name); })
14255
+ .filter(Boolean)
14256
+ .sort(function (a, b) { return a.localeCompare(b); });
14257
+ return normalized.join('|');
14258
+ }
14259
+ function buildAssistantCollectionRelationshipGraph(collectionNames) {
14260
+ var graph = new Map();
14261
+ var names = Array.isArray(collectionNames) ? collectionNames.map(function (name) { return normalizeOptionalString(name); }).filter(Boolean) : [];
14262
+ if (!names.length) {
14263
+ return graph;
14264
+ }
14265
+ var signature = buildAssistantCollectionGraphSignature(names);
14266
+ if (signature) {
14267
+ var cached = AI_ASSISTANT_RELATIONSHIP_GRAPH_CACHE.get(signature);
14268
+ var now = Date.now();
14269
+ if (cached && now - cached.updatedAt < AI_ASSISTANT_RELATIONSHIP_GRAPH_CACHE_TTL_MS) {
14270
+ return cached.graph;
14271
+ }
14272
+ }
14273
+ var knownFamilies = new Set(names
14274
+ .map(function (name) { return normalizeAssistantCollectionFamilyName(name); })
14275
+ .filter(Boolean));
14276
+ names.forEach(function (collectionName) {
14277
+ var fromFamily = normalizeAssistantCollectionFamilyName(collectionName);
14278
+ if (!fromFamily) {
14279
+ return;
14280
+ }
14281
+ var lookupMappings = getCollectionLookupMappings(collectionName);
14282
+ lookupMappings.forEach(function (mapping) {
14283
+ var toFamily = normalizeAssistantCollectionFamilyName(mapping.lookupCollection);
14284
+ if (!toFamily || !knownFamilies.has(toFamily)) {
14285
+ return;
14286
+ }
14287
+ addAssistantCollectionRelationshipEdge(graph, fromFamily, toFamily, 6);
14288
+ addAssistantCollectionRelationshipEdge(graph, toFamily, fromFamily, 4);
14289
+ });
14290
+ var schemaFields = getCollectionSchemaFieldNames(collectionName);
14291
+ schemaFields.forEach(function (field) {
14292
+ var normalizedPath = normalizeLookupPath(field);
14293
+ if (!normalizedPath) {
14294
+ return;
14295
+ }
14296
+ var leaf = normalizedPath.split('.').pop() || normalizedPath;
14297
+ if (!/^id_[a-z0-9_]+$/i.test(leaf)) {
14298
+ return;
14299
+ }
14300
+ var token = normalizeOptionalString(leaf.slice(3));
14301
+ if (!token) {
14302
+ return;
14303
+ }
14304
+ var aliasCandidates = mergeAssistantHintValues(resolveAssistantBridgeCollectionAliasCandidates(token), resolveAssistantBridgeCollectionAliasCandidates(normalizeCollectionKey(token)), [token, "".concat(token, "s")]);
14305
+ aliasCandidates.forEach(function (candidate) {
14306
+ var toFamily = normalizeAssistantCollectionFamilyName(candidate);
14307
+ if (!toFamily || !knownFamilies.has(toFamily)) {
14308
+ return;
14309
+ }
14310
+ addAssistantCollectionRelationshipEdge(graph, fromFamily, toFamily, 3);
14311
+ addAssistantCollectionRelationshipEdge(graph, toFamily, fromFamily, 2);
14312
+ });
14313
+ });
14314
+ });
14315
+ if (signature) {
14316
+ AI_ASSISTANT_RELATIONSHIP_GRAPH_CACHE.set(signature, {
14317
+ graph: graph,
14318
+ updatedAt: Date.now()
14319
+ });
14320
+ }
14321
+ return graph;
14322
+ }
14323
+ function resolveAssistantRelationshipFallbackCandidates(collection, collectionNames, triedCollections) {
14324
+ var currentFamily = normalizeAssistantCollectionFamilyName(collection);
14325
+ if (!currentFamily) {
14326
+ return [];
14327
+ }
14328
+ var graph = buildAssistantCollectionRelationshipGraph(collectionNames || []);
14329
+ var familyScores = new Map();
14330
+ var depthByFamily = new Map();
14331
+ var queue = [{ family: currentFamily, depth: 0 }];
14332
+ depthByFamily.set(currentFamily, 0);
14333
+ var _loop_9 = function () {
14334
+ var current = queue.shift();
14335
+ if (!current) {
14336
+ return "continue";
14337
+ }
14338
+ if (current.depth >= 2) {
14339
+ return "continue";
14340
+ }
14341
+ var neighbors = graph.get(current.family);
14342
+ if (!neighbors || !neighbors.size) {
14343
+ return "continue";
14344
+ }
14345
+ Array.from(neighbors.entries()).forEach(function (_a) {
14346
+ var _b = __read(_a, 2), neighborFamily = _b[0], weight = _b[1];
14347
+ if (!neighborFamily || neighborFamily === currentFamily || !Number.isFinite(weight) || weight <= 0) {
14348
+ return;
14349
+ }
14350
+ var nextDepth = current.depth + 1;
14351
+ var currentBestDepth = depthByFamily.get(neighborFamily);
14352
+ if (typeof currentBestDepth !== 'number' || nextDepth < currentBestDepth) {
14353
+ depthByFamily.set(neighborFamily, nextDepth);
14354
+ if (nextDepth < 2) {
14355
+ queue.push({ family: neighborFamily, depth: nextDepth });
14356
+ }
14357
+ }
14358
+ var depthFactor = nextDepth === 1 ? 1 : 0.55;
14359
+ var score = weight * depthFactor;
14360
+ if (score > (familyScores.get(neighborFamily) || 0)) {
14361
+ familyScores.set(neighborFamily, score);
14362
+ }
14363
+ });
14364
+ };
14365
+ while (queue.length) {
14366
+ _loop_9();
14367
+ }
14368
+ var preferredCollections = Array.from(familyScores.entries())
14369
+ .map(function (_a) {
14370
+ var _b = __read(_a, 2), family = _b[0], score = _b[1];
14371
+ var preferred = resolveAssistantPreferredCollectionForFamily(family, collectionNames || []);
14372
+ return { family: family, score: score, preferred: normalizeOptionalString(preferred) };
14373
+ })
14374
+ .filter(function (entry) { return !!entry.preferred; })
14375
+ .sort(function (a, b) {
14376
+ if (a.score !== b.score) {
14377
+ return b.score - a.score;
14378
+ }
14379
+ return (a.preferred || '').localeCompare(b.preferred || '');
14380
+ })
14381
+ .map(function (entry) { return entry.preferred; })
14382
+ .filter(function (preferred) { return !hasAssistantCollectionBeenTried(triedCollections, preferred); });
14383
+ return Array.from(new Set(preferredCollections));
14384
+ }
13154
14385
  function resolveAssistantCrossCollectionFallbackCandidates(collection) {
13155
14386
  var normalized = normalizeAssistantCollectionFamilyName(collection);
13156
14387
  if (!normalized) {
@@ -13173,7 +14404,84 @@ function resolveAssistantCrossCollectionFallbackCandidates(collection) {
13173
14404
  }
13174
14405
  return Array.from(candidates);
13175
14406
  }
13176
- function resolveAssistantAvailableCrossCollectionFallbacksFromNames(collection, triedCollections, collectionNames) {
14407
+ function normalizeAssistantFieldHints(fieldHints) {
14408
+ if (!Array.isArray(fieldHints) || !fieldHints.length) {
14409
+ return [];
14410
+ }
14411
+ var normalized = fieldHints
14412
+ .map(function (value) { return normalizeLookupPath(value); })
14413
+ .filter(Boolean);
14414
+ return Array.from(new Set(normalized));
14415
+ }
14416
+ function scoreAssistantFallbackCandidateFieldCoverage(candidate, fieldHints) {
14417
+ var hints = normalizeAssistantFieldHints(fieldHints || []);
14418
+ if (!hints.length) {
14419
+ return 0;
14420
+ }
14421
+ var fields = getCollectionSchemaFieldNames(candidate);
14422
+ if (!fields.length) {
14423
+ return 0;
14424
+ }
14425
+ var normalizedFields = fields
14426
+ .map(function (field) { return normalizeLookupPath(field); })
14427
+ .filter(Boolean);
14428
+ var fieldSet = new Set(normalizedFields);
14429
+ var leafSet = new Set(normalizedFields.map(function (field) { return field.split('.').pop() || field; }));
14430
+ var rootSet = new Set(normalizedFields.map(function (field) { return field.split('.')[0] || field; }));
14431
+ var score = 0;
14432
+ hints.forEach(function (hint) {
14433
+ if (fieldSet.has(hint)) {
14434
+ score += 6;
14435
+ return;
14436
+ }
14437
+ var leaf = hint.split('.').pop() || hint;
14438
+ if (leafSet.has(leaf)) {
14439
+ score += 3;
14440
+ return;
14441
+ }
14442
+ var root = hint.split('.')[0] || hint;
14443
+ if (rootSet.has(root)) {
14444
+ score += 1;
14445
+ }
14446
+ if (/^id_[a-z0-9_]+$/i.test(leaf)) {
14447
+ var idToken = normalizeOptionalString(leaf.slice(3)).toLowerCase();
14448
+ var family = normalizeAssistantCollectionFamilyName(candidate);
14449
+ if (idToken && family && family.includes(idToken)) {
14450
+ score += 2;
14451
+ }
14452
+ }
14453
+ });
14454
+ var hintTokens = mergeAssistantHintValues.apply(void 0, __spreadArray([], __read(hints.map(function (value) { return tokenizeCollectionText(value); })), false));
14455
+ if (hintTokens.length) {
14456
+ score += (0, common_1.round)(scoreCollectionMatch(hintTokens, candidate) / 4);
14457
+ }
14458
+ return score;
14459
+ }
14460
+ function rankAssistantFallbackCandidatesByFieldHints(candidates, fieldHints) {
14461
+ var normalizedCandidates = Array.isArray(candidates) ? candidates.filter(Boolean) : [];
14462
+ if (normalizedCandidates.length <= 1) {
14463
+ return normalizedCandidates;
14464
+ }
14465
+ var hints = normalizeAssistantFieldHints(fieldHints || []);
14466
+ if (!hints.length) {
14467
+ return normalizedCandidates;
14468
+ }
14469
+ return normalizedCandidates
14470
+ .map(function (candidate, index) { return ({
14471
+ candidate: candidate,
14472
+ coverageScore: scoreAssistantFallbackCandidateFieldCoverage(candidate, hints),
14473
+ originalIndex: index
14474
+ }); })
14475
+ .sort(function (a, b) {
14476
+ if (a.coverageScore !== b.coverageScore) {
14477
+ return b.coverageScore - a.coverageScore;
14478
+ }
14479
+ return a.originalIndex - b.originalIndex;
14480
+ })
14481
+ .map(function (entry) { return entry.candidate; });
14482
+ }
14483
+ function resolveAssistantAvailableCrossCollectionFallbacksFromNames(collection, triedCollections, collectionNames, options) {
14484
+ var _a;
13177
14485
  var candidates = resolveAssistantCrossCollectionFallbackCandidates(collection);
13178
14486
  var namesByFamily = new Map();
13179
14487
  (collectionNames || []).forEach(function (name) {
@@ -13205,6 +14513,8 @@ function resolveAssistantAvailableCrossCollectionFallbacksFromNames(collection,
13205
14513
  }
13206
14514
  available.push(preferred);
13207
14515
  };
14516
+ var relationshipCandidates = resolveAssistantRelationshipFallbackCandidates(collection, collectionNames || [], triedCollections);
14517
+ relationshipCandidates.forEach(pushPreferredCandidate);
13208
14518
  candidates.forEach(pushPreferredCandidate);
13209
14519
  var collectionTokenSeed = normalizeAssistantCollectionFamilyName(collection) || normalizeOptionalString(collection);
13210
14520
  var requestedTokens = tokenizeCollectionText(collectionTokenSeed);
@@ -13216,9 +14526,12 @@ function resolveAssistantAvailableCrossCollectionFallbacksFromNames(collection,
13216
14526
  .slice(0, 8)
13217
14527
  .forEach(function (entry) { return pushPreferredCandidate(entry.name); });
13218
14528
  }
14529
+ if ((_a = options === null || options === void 0 ? void 0 : options.fieldHints) === null || _a === void 0 ? void 0 : _a.length) {
14530
+ return rankAssistantFallbackCandidatesByFieldHints(available, options.fieldHints);
14531
+ }
13219
14532
  return available;
13220
14533
  }
13221
- function resolveAssistantAvailableCrossCollectionFallbacks(db, dbName, collection, triedCollections) {
14534
+ function resolveAssistantAvailableCrossCollectionFallbacks(db, dbName, collection, triedCollections, options) {
13222
14535
  return __awaiter(this, void 0, void 0, function () {
13223
14536
  var collectionNames;
13224
14537
  return __generator(this, function (_a) {
@@ -13226,7 +14539,7 @@ function resolveAssistantAvailableCrossCollectionFallbacks(db, dbName, collectio
13226
14539
  case 0: return [4 /*yield*/, listAssistantCollections(db, dbName)];
13227
14540
  case 1:
13228
14541
  collectionNames = _a.sent();
13229
- return [2 /*return*/, resolveAssistantAvailableCrossCollectionFallbacksFromNames(collection, triedCollections, collectionNames)];
14542
+ return [2 /*return*/, resolveAssistantAvailableCrossCollectionFallbacksFromNames(collection, triedCollections, collectionNames, options)];
13230
14543
  }
13231
14544
  });
13232
14545
  });
@@ -13333,20 +14646,61 @@ function resolveAssistantFallbackDimensionFields(documents) {
13333
14646
  });
13334
14647
  return dimensions;
13335
14648
  }
13336
- function shouldAcceptAssistantFallbackDocuments(documents) {
14649
+ function evaluateAssistantFallbackDocumentsQuality(documents, options) {
13337
14650
  var docs = Array.isArray(documents)
13338
14651
  ? documents.filter(function (doc) { return doc && typeof doc === 'object' && !Array.isArray(doc); })
13339
14652
  : [];
13340
14653
  if (!docs.length) {
13341
- return false;
14654
+ return {
14655
+ accepted: false,
14656
+ rowCount: 0,
14657
+ dimensionFields: [],
14658
+ bestFillRate: 0,
14659
+ averageFillRate: 0
14660
+ };
13342
14661
  }
13343
- var dimensionFields = resolveAssistantFallbackDimensionFields(docs);
14662
+ var rowCount = docs.length;
14663
+ var preferredFields = normalizeAggregateFieldList((Array.isArray(options === null || options === void 0 ? void 0 : options.preferredDimensionFields) ? options === null || options === void 0 ? void 0 : options.preferredDimensionFields : [])
14664
+ .filter(function (field) { return field && docs.some(function (doc) { return Object.prototype.hasOwnProperty.call(doc, field); }); }));
14665
+ var inferredFields = resolveAssistantFallbackDimensionFields(docs);
14666
+ var dimensionFields = normalizeAggregateFieldList(__spreadArray(__spreadArray([], __read(preferredFields), false), __read(inferredFields), false));
14667
+ var requiresDimensions = (options === null || options === void 0 ? void 0 : options.requireDimensionFields) === true;
13344
14668
  if (!dimensionFields.length) {
13345
- return true;
14669
+ return {
14670
+ accepted: !requiresDimensions,
14671
+ rowCount: rowCount,
14672
+ dimensionFields: dimensionFields,
14673
+ bestFillRate: 0,
14674
+ averageFillRate: 0
14675
+ };
13346
14676
  }
13347
- return docs.some(function (doc) {
13348
- return dimensionFields.some(function (field) { return isAssistantNonEmptyDimensionValue(doc[field]); });
14677
+ var fillStats = dimensionFields.map(function (field) {
14678
+ var nonEmpty = 0;
14679
+ docs.forEach(function (doc) {
14680
+ if (isAssistantNonEmptyDimensionValue(doc[field])) {
14681
+ nonEmpty += 1;
14682
+ }
14683
+ });
14684
+ return {
14685
+ field: field,
14686
+ fillRate: rowCount ? (nonEmpty / rowCount) : 0
14687
+ };
13349
14688
  });
14689
+ var best = fillStats
14690
+ .slice()
14691
+ .sort(function (a, b) { return b.fillRate - a.fillRate; })[0];
14692
+ var averageFillRate = fillStats.length
14693
+ ? (fillStats.reduce(function (sum, current) { return sum + current.fillRate; }, 0) / fillStats.length)
14694
+ : 0;
14695
+ var defaultMinFillRate = requiresDimensions ? 0.35 : 0.1;
14696
+ var minFillRate = typeof (options === null || options === void 0 ? void 0 : options.minDimensionFillRate) === 'number'
14697
+ ? Math.min(Math.max(options.minDimensionFillRate, 0), 1)
14698
+ : defaultMinFillRate;
14699
+ var accepted = !!best && best.fillRate >= minFillRate;
14700
+ return __assign(__assign({ accepted: accepted, rowCount: rowCount, dimensionFields: dimensionFields }, (best ? { bestField: best.field } : {})), { bestFillRate: best ? best.fillRate : 0, averageFillRate: averageFillRate });
14701
+ }
14702
+ function shouldAcceptAssistantFallbackDocuments(documents, options) {
14703
+ return evaluateAssistantFallbackDocumentsQuality(documents, options).accepted;
13350
14704
  }
13351
14705
  function collectAggregateReferencedFieldPaths(pipeline) {
13352
14706
  var fields = new Set();
@@ -13976,7 +15330,7 @@ function expandAggregateDateMatchFallback(pipeline, schemaFields) {
13976
15330
  if (!Array.isArray(pipeline)) {
13977
15331
  return null;
13978
15332
  }
13979
- var _loop_8 = function (i) {
15333
+ var _loop_10 = function (i) {
13980
15334
  var stage = pipeline[i];
13981
15335
  if (!stage || typeof stage !== 'object' || !stage.$match || typeof stage.$match !== 'object') {
13982
15336
  return "continue";
@@ -14024,7 +15378,7 @@ function expandAggregateDateMatchFallback(pipeline, schemaFields) {
14024
15378
  return { value: { pipeline: updated, fields: Array.from(addedFields) } };
14025
15379
  };
14026
15380
  for (var i = 0; i < pipeline.length; i += 1) {
14027
- var state_6 = _loop_8(i);
15381
+ var state_6 = _loop_10(i);
14028
15382
  if (typeof state_6 === "object")
14029
15383
  return state_6.value;
14030
15384
  }
@@ -14784,12 +16138,42 @@ function directoryExists(target) {
14784
16138
  });
14785
16139
  });
14786
16140
  }
16141
+ function parseAssistantPathList(value) {
16142
+ var normalized = normalizeOptionalString(value);
16143
+ if (!normalized) {
16144
+ return [];
16145
+ }
16146
+ return normalized
16147
+ .split(/[\n,;]+/g)
16148
+ .map(function (entry) { return normalizeOptionalString(entry); })
16149
+ .filter(Boolean);
16150
+ }
16151
+ function buildAssistantParentDirectoryCandidates(basePath, maxDepth) {
16152
+ if (maxDepth === void 0) { maxDepth = 4; }
16153
+ var normalized = normalizeOptionalString(basePath);
16154
+ if (!normalized) {
16155
+ return [];
16156
+ }
16157
+ var results = [];
16158
+ var current = path.resolve(normalized);
16159
+ for (var depth = 0; depth < Math.max(maxDepth, 0); depth += 1) {
16160
+ var parent_1 = path.dirname(current);
16161
+ if (!parent_1 || parent_1 === current) {
16162
+ break;
16163
+ }
16164
+ results.push(parent_1);
16165
+ current = parent_1;
16166
+ }
16167
+ return results;
16168
+ }
14787
16169
  function buildAssistantWorkspaceRootCandidates(params) {
14788
16170
  var serverConfig = (params === null || params === void 0 ? void 0 : params.serverConfig) || resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
14789
16171
  var env = (params === null || params === void 0 ? void 0 : params.env) || process.env || {};
14790
16172
  var cwdValue = normalizeOptionalString((params === null || params === void 0 ? void 0 : params.cwd) || process.cwd());
14791
16173
  var dirnameValue = normalizeOptionalString((params === null || params === void 0 ? void 0 : params.dirname) || __dirname);
14792
- var pathCandidates = [
16174
+ var homeDir = normalizeOptionalString(os.homedir());
16175
+ var configuredRoots = mergeAssistantHintValues(parseAssistantPathList(serverConfig['AI_ASSISTANT_WORKSPACE_ROOTS']), parseAssistantPathList(env['AI_ASSISTANT_WORKSPACE_ROOTS']), parseAssistantPathList(serverConfig['AI_ASSISTANT_GIT_ROOTS']), parseAssistantPathList(env['AI_ASSISTANT_GIT_ROOTS']));
16176
+ var pathCandidates = __spreadArray(__spreadArray(__spreadArray([
14793
16177
  serverConfig['AI_ASSISTANT_WORKSPACE_ROOT'],
14794
16178
  env['AI_ASSISTANT_WORKSPACE_ROOT'],
14795
16179
  serverConfig['AI_ASSISTANT_ROOT_WORKSPACE'],
@@ -14801,8 +16185,10 @@ function buildAssistantWorkspaceRootCandidates(params) {
14801
16185
  '/var/app/current',
14802
16186
  cwdValue,
14803
16187
  dirnameValue ? path.resolve(dirnameValue, '../../..') : '',
14804
- dirnameValue ? path.resolve(dirnameValue, '../../../..') : ''
14805
- ];
16188
+ dirnameValue ? path.resolve(dirnameValue, '../../../..') : '',
16189
+ homeDir ? path.resolve(homeDir, 'ResolveIO') : '',
16190
+ homeDir ? path.resolve(homeDir, 'workspace') : ''
16191
+ ], __read(configuredRoots), false), __read(buildAssistantParentDirectoryCandidates(cwdValue, 5)), false), __read(buildAssistantParentDirectoryCandidates(dirnameValue, 5)), false);
14806
16192
  var seen = new Set();
14807
16193
  var candidates = [];
14808
16194
  pathCandidates.forEach(function (value) {
@@ -15502,9 +16888,10 @@ function resolveAssistantPlannerEnabled() {
15502
16888
  || process.env.AI_ASSISTANT_CODEX_PLANNER_ENABLED);
15503
16889
  return raw === undefined ? true : raw === true;
15504
16890
  }
15505
- function resolveAssistantPlannerKnownRoutes() {
16891
+ function resolveAssistantPlannerKnownRoutes(user, isSuperAdmin) {
15506
16892
  var e_43, _a;
15507
16893
  var _b;
16894
+ if (isSuperAdmin === void 0) { isSuperAdmin = false; }
15508
16895
  var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
15509
16896
  var unique = new Set();
15510
16897
  try {
@@ -15523,7 +16910,12 @@ function resolveAssistantPlannerKnownRoutes() {
15523
16910
  }
15524
16911
  finally { if (e_43) throw e_43.error; }
15525
16912
  }
15526
- return Array.from(unique).slice(0, AI_ASSISTANT_PLANNER_MAX_ROUTES);
16913
+ var normalizedRoutes = Array.from(unique);
16914
+ var allowedRoutes = collectAssistantAllowedRoutesForUser(user, normalizedRoutes, isSuperAdmin);
16915
+ if (allowedRoutes.length) {
16916
+ return allowedRoutes.slice(0, AI_ASSISTANT_PLANNER_MAX_ROUTES);
16917
+ }
16918
+ return normalizedRoutes.slice(0, AI_ASSISTANT_PLANNER_MAX_ROUTES);
15527
16919
  }
15528
16920
  function buildAssistantPlannerUserSnapshot(user, inputClientId) {
15529
16921
  var _a, _b, _c, _d, _e;
@@ -15572,7 +16964,9 @@ function buildAssistantPlannerPrompt(params) {
15572
16964
  known_routes_json_array: JSON.stringify(params.knownRoutes || []),
15573
16965
  user_json: JSON.stringify(userSnapshot || {}),
15574
16966
  collection_hints_json_array: JSON.stringify(params.collectionHints || []),
15575
- field_hints_json_array: JSON.stringify(params.fieldHints || [])
16967
+ field_hints_json_array: JSON.stringify(params.fieldHints || []),
16968
+ method_hints_json_array: JSON.stringify(params.methodHints || []),
16969
+ publication_hints_json_array: JSON.stringify(params.publicationHints || [])
15576
16970
  };
15577
16971
  var userPrompt = applyTemplate(AI_ASSISTANT_PLANNER_USER_PROMPT_TEMPLATE, templateData);
15578
16972
  return "System:\n".concat(AI_ASSISTANT_PLANNER_SYSTEM_PROMPT, "\n\nUser:\n").concat(userPrompt).trim();
@@ -15623,6 +17017,18 @@ function buildAssistantContext(input, userContext) {
15623
17017
  lines.push(hint);
15624
17018
  });
15625
17019
  }
17020
+ var methodHints = Array.isArray(userContext === null || userContext === void 0 ? void 0 : userContext.methodHints)
17021
+ ? userContext.methodHints.filter(Boolean)
17022
+ : [];
17023
+ if (methodHints.length) {
17024
+ lines.push("Method hints: ".concat(methodHints.join(', ')));
17025
+ }
17026
+ var publicationHints = Array.isArray(userContext === null || userContext === void 0 ? void 0 : userContext.publicationHints)
17027
+ ? userContext.publicationHints.filter(Boolean)
17028
+ : [];
17029
+ if (publicationHints.length) {
17030
+ lines.push("Publication hints: ".concat(publicationHints.join(', ')));
17031
+ }
15626
17032
  var recentToolError = normalizeOptionalString(userContext === null || userContext === void 0 ? void 0 : userContext.recentToolError);
15627
17033
  if (recentToolError) {
15628
17034
  lines.push("Most recent data-query error: ".concat(recentToolError));
@@ -16509,7 +17915,7 @@ function summarizeAssistantChangeThemes(commits) {
16509
17915
  }
16510
17916
  function resolveAssistantGitRoot(startDir) {
16511
17917
  return __awaiter(this, void 0, void 0, function () {
16512
- var current, gitPath, _a, parent_1;
17918
+ var current, gitPath, _a, parent_2;
16513
17919
  return __generator(this, function (_b) {
16514
17920
  switch (_b.label) {
16515
17921
  case 0:
@@ -16534,24 +17940,43 @@ function resolveAssistantGitRoot(startDir) {
16534
17940
  if (_a) {
16535
17941
  return [2 /*return*/, current];
16536
17942
  }
16537
- parent_1 = path.dirname(current);
16538
- if (!parent_1 || parent_1 === current) {
17943
+ parent_2 = path.dirname(current);
17944
+ if (!parent_2 || parent_2 === current) {
16539
17945
  return [3 /*break*/, 5];
16540
17946
  }
16541
- current = parent_1;
17947
+ current = parent_2;
16542
17948
  return [3 /*break*/, 1];
16543
17949
  case 5: return [2 /*return*/, ''];
16544
17950
  }
16545
17951
  });
16546
17952
  });
16547
17953
  }
17954
+ function shouldSkipAssistantGitDiscoveryDirectory(name) {
17955
+ var normalized = normalizeOptionalString(name).toLowerCase();
17956
+ if (!normalized) {
17957
+ return true;
17958
+ }
17959
+ var skipNames = new Set([
17960
+ 'node_modules',
17961
+ 'dist',
17962
+ 'build',
17963
+ 'tmp',
17964
+ 'temp',
17965
+ 'coverage',
17966
+ 'logs',
17967
+ 'log',
17968
+ '.next',
17969
+ '.nuxt'
17970
+ ]);
17971
+ return normalized.startsWith('.') || skipNames.has(normalized);
17972
+ }
16548
17973
  function resolveAssistantWorkspaceGitRoots(workspaceRoot) {
16549
17974
  return __awaiter(this, void 0, void 0, function () {
16550
- var roots, seen, push, _a, entries, _b, skipNames, entries_1, entries_1_1, entry, name_1, candidate, gitPath, _c, e_45_1;
16551
- var e_45, _d;
16552
- var _e;
16553
- return __generator(this, function (_f) {
16554
- switch (_f.label) {
17975
+ var roots, seen, push, _a, configuredRoots, configuredRoots_1, configuredRoots_1_1, configuredRoot, _b, e_45_1, queue, queued, enqueue, next, entries, _c, entries_1, entries_1_1, entry, childName, candidate, gitPath, _d, e_46_1;
17976
+ var e_45, _e, e_46, _f;
17977
+ var _g;
17978
+ return __generator(this, function (_h) {
17979
+ switch (_h.label) {
16555
17980
  case 0:
16556
17981
  roots = [];
16557
17982
  seen = new Set();
@@ -16570,69 +17995,126 @@ function resolveAssistantWorkspaceGitRoots(workspaceRoot) {
16570
17995
  _a = push;
16571
17996
  return [4 /*yield*/, resolveAssistantGitRoot(workspaceRoot)];
16572
17997
  case 1:
16573
- _a.apply(void 0, [_f.sent()]);
16574
- entries = [];
16575
- _f.label = 2;
17998
+ _a.apply(void 0, [_h.sent()]);
17999
+ configuredRoots = mergeAssistantHintValues(parseAssistantPathList(process.env.AI_ASSISTANT_GIT_ROOTS), parseAssistantPathList(process.env.AI_ASSISTANT_WORKSPACE_ROOTS));
18000
+ _h.label = 2;
16576
18001
  case 2:
16577
- _f.trys.push([2, 4, , 5]);
16578
- return [4 /*yield*/, fs_1.promises.readdir(workspaceRoot, { withFileTypes: true })];
18002
+ _h.trys.push([2, 7, 8, 9]);
18003
+ configuredRoots_1 = __values(configuredRoots), configuredRoots_1_1 = configuredRoots_1.next();
18004
+ _h.label = 3;
16579
18005
  case 3:
16580
- entries = _f.sent();
16581
- return [3 /*break*/, 5];
18006
+ if (!!configuredRoots_1_1.done) return [3 /*break*/, 6];
18007
+ configuredRoot = configuredRoots_1_1.value;
18008
+ if (roots.length >= AI_ASSISTANT_GIT_DISCOVERY_MAX_ROOTS) {
18009
+ return [3 /*break*/, 6];
18010
+ }
18011
+ _b = push;
18012
+ return [4 /*yield*/, resolveAssistantGitRoot(configuredRoot)];
16582
18013
  case 4:
16583
- _b = _f.sent();
16584
- entries = [];
16585
- return [3 /*break*/, 5];
18014
+ _b.apply(void 0, [_h.sent()]);
18015
+ _h.label = 5;
16586
18016
  case 5:
16587
- skipNames = new Set(['node_modules', 'dist', 'build', 'tmp', 'temp', 'coverage']);
16588
- _f.label = 6;
16589
- case 6:
16590
- _f.trys.push([6, 13, 14, 15]);
16591
- entries_1 = __values(entries), entries_1_1 = entries_1.next();
16592
- _f.label = 7;
18017
+ configuredRoots_1_1 = configuredRoots_1.next();
18018
+ return [3 /*break*/, 3];
18019
+ case 6: return [3 /*break*/, 9];
16593
18020
  case 7:
16594
- if (!!entries_1_1.done) return [3 /*break*/, 12];
18021
+ e_45_1 = _h.sent();
18022
+ e_45 = { error: e_45_1 };
18023
+ return [3 /*break*/, 9];
18024
+ case 8:
18025
+ try {
18026
+ if (configuredRoots_1_1 && !configuredRoots_1_1.done && (_e = configuredRoots_1.return)) _e.call(configuredRoots_1);
18027
+ }
18028
+ finally { if (e_45) throw e_45.error; }
18029
+ return [7 /*endfinally*/];
18030
+ case 9:
18031
+ queue = [];
18032
+ queued = new Set();
18033
+ enqueue = function (dir, depth) {
18034
+ var normalized = normalizeOptionalString(dir);
18035
+ if (!normalized) {
18036
+ return;
18037
+ }
18038
+ var resolved = path.resolve(normalized);
18039
+ if (queued.has(resolved)) {
18040
+ return;
18041
+ }
18042
+ queued.add(resolved);
18043
+ queue.push({ dir: resolved, depth: depth });
18044
+ };
18045
+ enqueue(workspaceRoot, 0);
18046
+ configuredRoots.forEach(function (root) { return enqueue(root, 0); });
18047
+ _h.label = 10;
18048
+ case 10:
18049
+ if (!(queue.length && roots.length < AI_ASSISTANT_GIT_DISCOVERY_MAX_ROOTS)) return [3 /*break*/, 24];
18050
+ next = queue.shift();
18051
+ if (!next) {
18052
+ return [3 /*break*/, 10];
18053
+ }
18054
+ entries = [];
18055
+ _h.label = 11;
18056
+ case 11:
18057
+ _h.trys.push([11, 13, , 14]);
18058
+ return [4 /*yield*/, fs_1.promises.readdir(next.dir, { withFileTypes: true })];
18059
+ case 12:
18060
+ entries = _h.sent();
18061
+ return [3 /*break*/, 14];
18062
+ case 13:
18063
+ _c = _h.sent();
18064
+ entries = [];
18065
+ return [3 /*break*/, 14];
18066
+ case 14:
18067
+ _h.trys.push([14, 21, 22, 23]);
18068
+ entries_1 = (e_46 = void 0, __values(entries)), entries_1_1 = entries_1.next();
18069
+ _h.label = 15;
18070
+ case 15:
18071
+ if (!!entries_1_1.done) return [3 /*break*/, 20];
16595
18072
  entry = entries_1_1.value;
16596
- if (roots.length >= 12) {
16597
- return [3 /*break*/, 12];
18073
+ if (roots.length >= AI_ASSISTANT_GIT_DISCOVERY_MAX_ROOTS) {
18074
+ return [3 /*break*/, 20];
16598
18075
  }
16599
- if (!((_e = entry === null || entry === void 0 ? void 0 : entry.isDirectory) === null || _e === void 0 ? void 0 : _e.call(entry))) {
16600
- return [3 /*break*/, 11];
18076
+ if (!((_g = entry === null || entry === void 0 ? void 0 : entry.isDirectory) === null || _g === void 0 ? void 0 : _g.call(entry))) {
18077
+ return [3 /*break*/, 19];
16601
18078
  }
16602
- name_1 = normalizeOptionalString(entry.name).toLowerCase();
16603
- if (!name_1 || name_1.startsWith('.') || skipNames.has(name_1)) {
16604
- return [3 /*break*/, 11];
18079
+ childName = normalizeOptionalString(entry.name);
18080
+ if (shouldSkipAssistantGitDiscoveryDirectory(childName)) {
18081
+ return [3 /*break*/, 19];
16605
18082
  }
16606
- candidate = path.join(workspaceRoot, entry.name);
18083
+ candidate = path.join(next.dir, childName);
16607
18084
  gitPath = path.join(candidate, '.git');
16608
18085
  return [4 /*yield*/, directoryExists(gitPath)];
16609
- case 8:
16610
- _c = (_f.sent());
16611
- if (_c) return [3 /*break*/, 10];
18086
+ case 16:
18087
+ _d = (_h.sent());
18088
+ if (_d) return [3 /*break*/, 18];
16612
18089
  return [4 /*yield*/, pathExists(gitPath)];
16613
- case 9:
16614
- _c = (_f.sent());
16615
- _f.label = 10;
16616
- case 10:
16617
- if (_c) {
18090
+ case 17:
18091
+ _d = (_h.sent());
18092
+ _h.label = 18;
18093
+ case 18:
18094
+ if (_d) {
16618
18095
  push(candidate);
18096
+ return [3 /*break*/, 19];
16619
18097
  }
16620
- _f.label = 11;
16621
- case 11:
18098
+ if (next.depth + 1 < AI_ASSISTANT_GIT_DISCOVERY_MAX_DEPTH) {
18099
+ enqueue(candidate, next.depth + 1);
18100
+ }
18101
+ _h.label = 19;
18102
+ case 19:
16622
18103
  entries_1_1 = entries_1.next();
16623
- return [3 /*break*/, 7];
16624
- case 12: return [3 /*break*/, 15];
16625
- case 13:
16626
- e_45_1 = _f.sent();
16627
- e_45 = { error: e_45_1 };
16628
18104
  return [3 /*break*/, 15];
16629
- case 14:
18105
+ case 20: return [3 /*break*/, 23];
18106
+ case 21:
18107
+ e_46_1 = _h.sent();
18108
+ e_46 = { error: e_46_1 };
18109
+ return [3 /*break*/, 23];
18110
+ case 22:
16630
18111
  try {
16631
- if (entries_1_1 && !entries_1_1.done && (_d = entries_1.return)) _d.call(entries_1);
18112
+ if (entries_1_1 && !entries_1_1.done && (_f = entries_1.return)) _f.call(entries_1);
16632
18113
  }
16633
- finally { if (e_45) throw e_45.error; }
18114
+ finally { if (e_46) throw e_46.error; }
16634
18115
  return [7 /*endfinally*/];
16635
- case 15: return [2 /*return*/, roots];
18116
+ case 23: return [3 /*break*/, 10];
18117
+ case 24: return [2 /*return*/, roots];
16636
18118
  }
16637
18119
  });
16638
18120
  });
@@ -16783,9 +18265,9 @@ function buildAssistantChangeHistoryUnavailableResponse(message, reason) {
16783
18265
  lines.push('- I could not read repository history in this environment right now, so exact rollout dates are unavailable.');
16784
18266
  }
16785
18267
  else {
16786
- lines.push('- Repository history is not accessible in this environment, so exact rollout dates are unavailable here.');
18268
+ lines.push('- I could not locate a readable git repository from configured workspace paths, so exact rollout dates are unavailable right now.');
16787
18269
  }
16788
- lines.push('- I can still explain current behavior now, and provide exact dates once repository history is available.');
18270
+ lines.push('- I can still explain current behavior now, and provide exact dates once repository history is reachable.');
16789
18271
  if (asksDuration) {
16790
18272
  lines.push('- Best-known timing: unable to confirm exact first release date from this runtime.');
16791
18273
  }
@@ -16796,10 +18278,189 @@ function buildAssistantChangeHistoryUnavailableResponse(message, reason) {
16796
18278
  generic: true
16797
18279
  };
16798
18280
  }
18281
+ function resolveAssistantChangeHistoryGitRepoUrls() {
18282
+ var serverConfig = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
18283
+ var rawValues = [
18284
+ serverConfig['AI_ASSISTANT_CHANGE_HISTORY_GIT_REPO_URL'],
18285
+ process.env.AI_ASSISTANT_CHANGE_HISTORY_GIT_REPO_URL,
18286
+ serverConfig['AI_ASSISTANT_GIT_REPO_URL'],
18287
+ process.env.AI_ASSISTANT_GIT_REPO_URL,
18288
+ serverConfig['AI_ASSISTANT_CHANGE_HISTORY_GIT_REPO_URLS'],
18289
+ process.env.AI_ASSISTANT_CHANGE_HISTORY_GIT_REPO_URLS,
18290
+ serverConfig['AI_ASSISTANT_GIT_REPO_URLS'],
18291
+ process.env.AI_ASSISTANT_GIT_REPO_URLS
18292
+ ];
18293
+ var urls = mergeAssistantHintValues.apply(void 0, __spreadArray([], __read(rawValues.map(function (value) { return parseAssistantPathList(value); })), false));
18294
+ return urls.filter(function (url) { return /^https?:\/\//i.test(url) || /^git@/i.test(url) || /^ssh:\/\//i.test(url); });
18295
+ }
18296
+ function resolveAssistantGitMirrorRootDir() {
18297
+ var serverConfig = resolveio_server_app_1.ResolveIOServer.getServerConfig() || {};
18298
+ var configured = normalizeOptionalString(serverConfig['AI_ASSISTANT_GIT_MIRROR_ROOT']
18299
+ || process.env.AI_ASSISTANT_GIT_MIRROR_ROOT);
18300
+ if (configured) {
18301
+ return path.resolve(configured);
18302
+ }
18303
+ return path.resolve(os.tmpdir(), 'resolveio-ai-assistant-git-mirrors');
18304
+ }
18305
+ function buildAssistantGitMirrorName(repoUrl) {
18306
+ var normalized = normalizeOptionalString(repoUrl);
18307
+ if (!normalized) {
18308
+ return 'repo';
18309
+ }
18310
+ var withoutSuffix = normalized.replace(/\.git$/i, '');
18311
+ var tail = withoutSuffix.split(/[/:]/g).filter(Boolean).slice(-2).join('-');
18312
+ var slug = normalizeOptionalString(tail)
18313
+ .toLowerCase()
18314
+ .replace(/[^a-z0-9_-]+/g, '-')
18315
+ .replace(/-+/g, '-')
18316
+ .replace(/^-|-$/g, '');
18317
+ return slug || 'repo';
18318
+ }
18319
+ function syncAssistantGitMirror(repoUrl) {
18320
+ return __awaiter(this, void 0, void 0, function () {
18321
+ var normalizedUrl, now, cached, _a, mirrorRoot, _b, targetRoot, hasGitDir, _c, _d, resolvedRoot;
18322
+ return __generator(this, function (_e) {
18323
+ switch (_e.label) {
18324
+ case 0:
18325
+ normalizedUrl = normalizeOptionalString(repoUrl);
18326
+ if (!normalizedUrl) {
18327
+ return [2 /*return*/, ''];
18328
+ }
18329
+ now = Date.now();
18330
+ cached = assistantGitMirrorCache.get(normalizedUrl);
18331
+ if (!(cached && now - cached.updatedAt < AI_ASSISTANT_GIT_MIRROR_CACHE_TTL_MS)) return [3 /*break*/, 4];
18332
+ return [4 /*yield*/, directoryExists(path.join(cached.root, '.git'))];
18333
+ case 1:
18334
+ _a = (_e.sent());
18335
+ if (_a) return [3 /*break*/, 3];
18336
+ return [4 /*yield*/, pathExists(path.join(cached.root, '.git'))];
18337
+ case 2:
18338
+ _a = (_e.sent());
18339
+ _e.label = 3;
18340
+ case 3:
18341
+ if (_a) {
18342
+ return [2 /*return*/, cached.root];
18343
+ }
18344
+ _e.label = 4;
18345
+ case 4:
18346
+ mirrorRoot = resolveAssistantGitMirrorRootDir();
18347
+ _e.label = 5;
18348
+ case 5:
18349
+ _e.trys.push([5, 7, , 8]);
18350
+ return [4 /*yield*/, fs_1.promises.mkdir(mirrorRoot, { recursive: true })];
18351
+ case 6:
18352
+ _e.sent();
18353
+ return [3 /*break*/, 8];
18354
+ case 7:
18355
+ _b = _e.sent();
18356
+ return [2 /*return*/, ''];
18357
+ case 8:
18358
+ targetRoot = path.join(mirrorRoot, buildAssistantGitMirrorName(normalizedUrl));
18359
+ return [4 /*yield*/, directoryExists(path.join(targetRoot, '.git'))];
18360
+ case 9:
18361
+ _c = (_e.sent());
18362
+ if (_c) return [3 /*break*/, 11];
18363
+ return [4 /*yield*/, pathExists(path.join(targetRoot, '.git'))];
18364
+ case 10:
18365
+ _c = (_e.sent());
18366
+ _e.label = 11;
18367
+ case 11:
18368
+ hasGitDir = _c;
18369
+ _e.label = 12;
18370
+ case 12:
18371
+ _e.trys.push([12, 17, , 18]);
18372
+ if (!!hasGitDir) return [3 /*break*/, 14];
18373
+ return [4 /*yield*/, execFileAsync('git', ['clone', '--depth', '400', '--no-single-branch', normalizedUrl, targetRoot], {
18374
+ timeout: AI_ASSISTANT_GIT_COMMAND_TIMEOUT_MS * 6,
18375
+ maxBuffer: 1024 * 1024 * 6
18376
+ })];
18377
+ case 13:
18378
+ _e.sent();
18379
+ return [3 /*break*/, 16];
18380
+ case 14:
18381
+ if (!resolveAssistantChangeHistoryFetchEnabled()) return [3 /*break*/, 16];
18382
+ return [4 /*yield*/, execFileAsync('git', ['fetch', '--all', '--prune', '--quiet'], {
18383
+ cwd: targetRoot,
18384
+ timeout: AI_ASSISTANT_GIT_COMMAND_TIMEOUT_MS * 2,
18385
+ maxBuffer: 1024 * 1024 * 6
18386
+ })];
18387
+ case 15:
18388
+ _e.sent();
18389
+ _e.label = 16;
18390
+ case 16: return [3 /*break*/, 18];
18391
+ case 17:
18392
+ _d = _e.sent();
18393
+ return [2 /*return*/, ''];
18394
+ case 18: return [4 /*yield*/, resolveAssistantGitRoot(targetRoot)];
18395
+ case 19:
18396
+ resolvedRoot = _e.sent();
18397
+ if (!resolvedRoot) {
18398
+ return [2 /*return*/, ''];
18399
+ }
18400
+ assistantGitMirrorCache.set(normalizedUrl, {
18401
+ root: resolvedRoot,
18402
+ updatedAt: now
18403
+ });
18404
+ return [2 /*return*/, resolvedRoot];
18405
+ }
18406
+ });
18407
+ });
18408
+ }
18409
+ function resolveAssistantChangeHistoryGitRoots(workspaceRoot) {
18410
+ return __awaiter(this, void 0, void 0, function () {
18411
+ var roots, repoUrls, mirroredRoots, repoUrls_1, repoUrls_1_1, repoUrl, mirrorRoot, e_47_1;
18412
+ var e_47, _a;
18413
+ return __generator(this, function (_b) {
18414
+ switch (_b.label) {
18415
+ case 0: return [4 /*yield*/, resolveAssistantWorkspaceGitRoots(workspaceRoot)];
18416
+ case 1:
18417
+ roots = _b.sent();
18418
+ if (roots.length) {
18419
+ return [2 /*return*/, roots];
18420
+ }
18421
+ repoUrls = resolveAssistantChangeHistoryGitRepoUrls();
18422
+ if (!repoUrls.length) {
18423
+ return [2 /*return*/, []];
18424
+ }
18425
+ mirroredRoots = [];
18426
+ _b.label = 2;
18427
+ case 2:
18428
+ _b.trys.push([2, 7, 8, 9]);
18429
+ repoUrls_1 = __values(repoUrls), repoUrls_1_1 = repoUrls_1.next();
18430
+ _b.label = 3;
18431
+ case 3:
18432
+ if (!!repoUrls_1_1.done) return [3 /*break*/, 6];
18433
+ repoUrl = repoUrls_1_1.value;
18434
+ return [4 /*yield*/, syncAssistantGitMirror(repoUrl)];
18435
+ case 4:
18436
+ mirrorRoot = _b.sent();
18437
+ if (mirrorRoot && !mirroredRoots.includes(mirrorRoot)) {
18438
+ mirroredRoots.push(mirrorRoot);
18439
+ }
18440
+ _b.label = 5;
18441
+ case 5:
18442
+ repoUrls_1_1 = repoUrls_1.next();
18443
+ return [3 /*break*/, 3];
18444
+ case 6: return [3 /*break*/, 9];
18445
+ case 7:
18446
+ e_47_1 = _b.sent();
18447
+ e_47 = { error: e_47_1 };
18448
+ return [3 /*break*/, 9];
18449
+ case 8:
18450
+ try {
18451
+ if (repoUrls_1_1 && !repoUrls_1_1.done && (_a = repoUrls_1.return)) _a.call(repoUrls_1);
18452
+ }
18453
+ finally { if (e_47) throw e_47.error; }
18454
+ return [7 /*endfinally*/];
18455
+ case 9: return [2 /*return*/, mirroredRoots];
18456
+ }
18457
+ });
18458
+ });
18459
+ }
16799
18460
  function resolveAssistantChangeHistoryFastPathResponse(params) {
16800
18461
  return __awaiter(this, void 0, void 0, function () {
16801
- var workspaceRoot, _a, gitRoots, featureKeywords, sawExecutionError, bestFallback, gitRoots_1, gitRoots_1_1, gitRoot, _b, branch, _c, _d, limit, historyDepth, rawHistory, commits, summary, hasKeywordMatches, _e, e_46_1;
16802
- var e_46, _f;
18462
+ var workspaceRoot, _a, gitRoots, featureKeywords, sawExecutionError, bestFallback, gitRoots_1, gitRoots_1_1, gitRoot, _b, branch, _c, _d, limit, historyDepth, rawHistory, commits, summary, hasKeywordMatches, _e, e_48_1;
18463
+ var e_48, _f;
16803
18464
  return __generator(this, function (_g) {
16804
18465
  switch (_g.label) {
16805
18466
  case 0:
@@ -16822,7 +18483,7 @@ function resolveAssistantChangeHistoryFastPathResponse(params) {
16822
18483
  if (!workspaceRoot) {
16823
18484
  return [2 /*return*/, buildAssistantChangeHistoryUnavailableResponse(params.message, 'no_repo')];
16824
18485
  }
16825
- return [4 /*yield*/, resolveAssistantWorkspaceGitRoots(workspaceRoot)];
18486
+ return [4 /*yield*/, resolveAssistantChangeHistoryGitRoots(workspaceRoot)];
16826
18487
  case 5:
16827
18488
  gitRoots = _g.sent();
16828
18489
  if (!gitRoots.length) {
@@ -16921,14 +18582,14 @@ function resolveAssistantChangeHistoryFastPathResponse(params) {
16921
18582
  return [3 /*break*/, 7];
16922
18583
  case 20: return [3 /*break*/, 23];
16923
18584
  case 21:
16924
- e_46_1 = _g.sent();
16925
- e_46 = { error: e_46_1 };
18585
+ e_48_1 = _g.sent();
18586
+ e_48 = { error: e_48_1 };
16926
18587
  return [3 /*break*/, 23];
16927
18588
  case 22:
16928
18589
  try {
16929
18590
  if (gitRoots_1_1 && !gitRoots_1_1.done && (_f = gitRoots_1.return)) _f.call(gitRoots_1);
16930
18591
  }
16931
- finally { if (e_46) throw e_46.error; }
18592
+ finally { if (e_48) throw e_48.error; }
16932
18593
  return [7 /*endfinally*/];
16933
18594
  case 23:
16934
18595
  if (bestFallback) {
@@ -17109,7 +18770,7 @@ function sanitizeAssistantResponse(value) {
17109
18770
  return normalizeAssistantRoutes(normalizedCurrency);
17110
18771
  }
17111
18772
  function evaluateAssistantGuardrails(message) {
17112
- var e_47, _a;
18773
+ var e_49, _a;
17113
18774
  var normalized = String(message || '').toLowerCase();
17114
18775
  var patterns = [
17115
18776
  {
@@ -17155,12 +18816,12 @@ function evaluateAssistantGuardrails(message) {
17155
18816
  }
17156
18817
  }
17157
18818
  }
17158
- catch (e_47_1) { e_47 = { error: e_47_1 }; }
18819
+ catch (e_49_1) { e_49 = { error: e_49_1 }; }
17159
18820
  finally {
17160
18821
  try {
17161
18822
  if (patterns_2_1 && !patterns_2_1.done && (_a = patterns_2.return)) _a.call(patterns_2);
17162
18823
  }
17163
- finally { if (e_47) throw e_47.error; }
18824
+ finally { if (e_49) throw e_49.error; }
17164
18825
  }
17165
18826
  return null;
17166
18827
  }
@@ -17275,7 +18936,7 @@ function tokenizeArithmeticExpression(expression) {
17275
18936
  return tokens;
17276
18937
  }
17277
18938
  function evaluateArithmeticExpression(expression) {
17278
- var e_48, _a, e_49, _b;
18939
+ var e_50, _a, e_51, _b;
17279
18940
  var tokens = tokenizeArithmeticExpression(expression);
17280
18941
  if (!tokens || !tokens.length) {
17281
18942
  return null;
@@ -17332,12 +18993,12 @@ function evaluateArithmeticExpression(expression) {
17332
18993
  prevToken = token;
17333
18994
  }
17334
18995
  }
17335
- catch (e_48_1) { e_48 = { error: e_48_1 }; }
18996
+ catch (e_50_1) { e_50 = { error: e_50_1 }; }
17336
18997
  finally {
17337
18998
  try {
17338
18999
  if (tokens_2_1 && !tokens_2_1.done && (_a = tokens_2.return)) _a.call(tokens_2);
17339
19000
  }
17340
- finally { if (e_48) throw e_48.error; }
19001
+ finally { if (e_50) throw e_50.error; }
17341
19002
  }
17342
19003
  while (ops.length) {
17343
19004
  var op = ops.pop();
@@ -17377,12 +19038,12 @@ function evaluateArithmeticExpression(expression) {
17377
19038
  stack.push(Number(token));
17378
19039
  }
17379
19040
  }
17380
- catch (e_49_1) { e_49 = { error: e_49_1 }; }
19041
+ catch (e_51_1) { e_51 = { error: e_51_1 }; }
17381
19042
  finally {
17382
19043
  try {
17383
19044
  if (output_1_1 && !output_1_1.done && (_b = output_1.return)) _b.call(output_1);
17384
19045
  }
17385
- finally { if (e_49) throw e_49.error; }
19046
+ finally { if (e_51) throw e_51.error; }
17386
19047
  }
17387
19048
  if (stack.length !== 1 || Number.isNaN(stack[0])) {
17388
19049
  return null;
@@ -17566,8 +19227,8 @@ function handleCodexUpload(id_conversation, file_name, content_base64, size, con
17566
19227
  }
17567
19228
  function readAttachmentContents(attachments) {
17568
19229
  return __awaiter(this, void 0, void 0, function () {
17569
- var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_2, type, readable, content, _a, e_50_1;
17570
- var e_50, _b;
19230
+ var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_52_1;
19231
+ var e_52, _b;
17571
19232
  return __generator(this, function (_c) {
17572
19233
  switch (_c.label) {
17573
19234
  case 0:
@@ -17609,7 +19270,7 @@ function readAttachmentContents(attachments) {
17609
19270
  return [3 /*break*/, 10];
17610
19271
  }
17611
19272
  ext = path.extname(localPath).toLowerCase();
17612
- name_2 = normalizeOptionalString(attachment.name) || path.basename(localPath);
19273
+ name_1 = normalizeOptionalString(attachment.name) || path.basename(localPath);
17613
19274
  type = normalizeOptionalString(attachment.type);
17614
19275
  readable = isReadableAttachment(type, ext);
17615
19276
  content = '';
@@ -17622,17 +19283,17 @@ function readAttachmentContents(attachments) {
17622
19283
  }
17623
19284
  return [3 /*break*/, 7];
17624
19285
  case 6:
17625
- content = "[".concat(name_2, " attached; binary content omitted]");
19286
+ content = "[".concat(name_1, " attached; binary content omitted]");
17626
19287
  _c.label = 7;
17627
19288
  case 7:
17628
19289
  totalChars += content.length;
17629
19290
  if (totalChars > limits.maxTotalAttachmentChars) {
17630
19291
  return [3 /*break*/, 10];
17631
19292
  }
17632
- chunks.push("File: ".concat(name_2, "\n").concat(content));
19293
+ chunks.push("File: ".concat(name_1, "\n").concat(content));
17633
19294
  cleaned.push({
17634
19295
  id: attachment.id,
17635
- name: name_2,
19296
+ name: name_1,
17636
19297
  type: type,
17637
19298
  size: stat.size,
17638
19299
  local_path: localPath
@@ -17646,14 +19307,14 @@ function readAttachmentContents(attachments) {
17646
19307
  return [3 /*break*/, 2];
17647
19308
  case 10: return [3 /*break*/, 13];
17648
19309
  case 11:
17649
- e_50_1 = _c.sent();
17650
- e_50 = { error: e_50_1 };
19310
+ e_52_1 = _c.sent();
19311
+ e_52 = { error: e_52_1 };
17651
19312
  return [3 /*break*/, 13];
17652
19313
  case 12:
17653
19314
  try {
17654
19315
  if (attachments_1_1 && !attachments_1_1.done && (_b = attachments_1.return)) _b.call(attachments_1);
17655
19316
  }
17656
- finally { if (e_50) throw e_50.error; }
19317
+ finally { if (e_52) throw e_52.error; }
17657
19318
  return [7 /*endfinally*/];
17658
19319
  case 13: return [2 /*return*/, {
17659
19320
  promptText: chunks.length ? "\n\nAttachments:\n".concat(chunks.join('\n\n')) : '',
@@ -17977,7 +19638,7 @@ function estimateUsage(messages, responseText, model) {
17977
19638
  };
17978
19639
  }
17979
19640
  function evaluateGuardrails(message) {
17980
- var e_51, _a;
19641
+ var e_53, _a;
17981
19642
  var normalized = String(message || '').toLowerCase();
17982
19643
  var patterns = [
17983
19644
  { 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.' },
@@ -17999,12 +19660,12 @@ function evaluateGuardrails(message) {
17999
19660
  }
18000
19661
  }
18001
19662
  }
18002
- catch (e_51_1) { e_51 = { error: e_51_1 }; }
19663
+ catch (e_53_1) { e_53 = { error: e_53_1 }; }
18003
19664
  finally {
18004
19665
  try {
18005
19666
  if (patterns_3_1 && !patterns_3_1.done && (_a = patterns_3.return)) _a.call(patterns_3);
18006
19667
  }
18007
- finally { if (e_51) throw e_51.error; }
19668
+ finally { if (e_53) throw e_53.error; }
18008
19669
  }
18009
19670
  return null;
18010
19671
  }