@resolveio/server-lib 20.15.6 → 20.15.8

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.
@@ -145,6 +145,7 @@ var AI_ASSISTANT_DISPLAY_STRING_LIMIT = 160;
145
145
  var AI_ASSISTANT_PROGRESS_PLACEHOLDER = 'Planning...';
146
146
  var AI_ASSISTANT_PROGRESS_TICK_MS = 5000;
147
147
  var AI_ASSISTANT_READ_PREFERENCE = 'secondary';
148
+ var AI_ASSISTANT_NAME_MATCH_FALLBACK_MAX_FIELDS = 12;
148
149
  var AI_ASSISTANT_PROGRESS_TICKS = [
149
150
  'Grabbing Data',
150
151
  'Drafting response'
@@ -246,6 +247,13 @@ var AI_ASSISTANT_COLLECTION_STOPWORDS = new Set([
246
247
  'missing',
247
248
  'overdue'
248
249
  ]);
250
+ var AI_ASSISTANT_TERM_SYNONYMS = [
251
+ {
252
+ label: 'truck treating jobs',
253
+ pattern: /\btruck\s+treating\s+jobs?\b/i,
254
+ expansions: ['truck treating deliveries', 'truck-treating-deliveries', 'truck treating route events']
255
+ }
256
+ ];
249
257
  var AI_ASSISTANT_SYSTEM_PROMPT = [
250
258
  'You are the ResolveIO in-app AI assistant running with read-only access to the codebase.',
251
259
  'Core rules:',
@@ -259,6 +267,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
259
267
  '- Step 1 (always): determine the target collections/models/modules/workflows using context, routes, and collection hints. Assume the user is non-technical and will not provide internal names.',
260
268
  '- Planning stage: regex/keyword scan the codebase for collectionName/model definitions, methods, publications, and Angular routes/modules to map user wording to internal names.',
261
269
  '- Map user wording to internal collections/fields yourself. Do not ask for property names unless required to run a query.',
270
+ '- Use term hints from context (synonym expansions) when mapping user language to collections.',
262
271
  '- Do not guess or invent collections/fields. If unsure, verify in the codebase or run a small Mongo read (limit 1-5) to learn the shape.',
263
272
  '- Prefer running a small Mongo read over asking multiple questions.',
264
273
  '- For any data request (counts, lists, breakdowns, recent/last items), you MUST run a MONGO_READ or MONGO_AGG before answering.',
@@ -275,6 +284,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
275
284
  '- When you reference database results, summarize first, then include a Markdown table.',
276
285
  '- When presenting record lists or aggregates, produce a Markdown table (pipes).',
277
286
  '- Never show raw JSON dumps.',
287
+ '- Do not invent placeholders like "Not available" or "N/A". If a value is missing in tool results, leave the cell blank or omit the column and note it briefly.',
278
288
  '- Do not include `_id` & `__v` & `id_<other collection _id property>` in tables by default.',
279
289
  '- If `_id` & `__v` & `id_<other collection _id property>` is needed, show it as `id` and shorten (e.g., first 6-8 chars) unless asked otherwise.',
280
290
  '- Rename `createdAt` to `Created At` and `updatedAt` to `Updated At` in tables.',
@@ -1039,11 +1049,21 @@ function executeAiAssistantCodexRun(payload, context) {
1039
1049
  insertResult = _d.sent();
1040
1050
  assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
1041
1051
  enqueueAssistantCodexRun(function () { return __awaiter(_this, void 0, void 0, function () {
1042
- var progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, dataQuestion, lastDirective, toolResponseDebug, toolError, collectionHints, dbName, db, hintText, _a, assistantContext, prompt_1, workspaceRoot, codexConfig, runOptions, responseText, directiveText, directive, directivePrompt, forcedDirective, _b, directivePrompt, forcedDirective, _c, cleanedResponseText, toolRequest, toolResponse, _d, toolPayload, followupPrompt, followupText, _e, error_2, error_3, finalNow, finalMetadata, finalAssistantDoc;
1043
- var _f;
1044
- return __generator(this, function (_g) {
1045
- switch (_g.label) {
1052
+ var runStart, steps, recordStep, progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, dataQuestion, lastDirective, toolResponseDebug, toolError, termHints, collectionHints, collectionTokenization, collectionRanking, collectionSelection, timingBreakdown, contextRoute, contextMode, hintSeed, termExpansion, hintText, baseTokens, expandedTokens, dbName, db, collectionNames, _a, assistantContext, prompt_1, workspaceRoot, codexConfig, runOptions, responseText, directiveText, directive, directivePrompt, directiveStart, forcedDirective, _b, initialStart, directivePrompt, forcedStart, forcedDirective, _c, cleanedResponseText, toolRequest, toolStart, toolResponse, _d, toolPayload, followupPrompt, followupStart, followupText, _e, error_2, error_3, finalNow, finishedAt, codexMs, draftingMs, finalMetadata, finalAssistantDoc;
1053
+ var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
1054
+ return __generator(this, function (_s) {
1055
+ switch (_s.label) {
1046
1056
  case 0:
1057
+ runStart = Date.now();
1058
+ steps = [];
1059
+ recordStep = function (step, details) {
1060
+ steps.push({
1061
+ step: step,
1062
+ at: new Date().toISOString(),
1063
+ ms: Date.now() - runStart,
1064
+ details: details
1065
+ });
1066
+ };
1047
1067
  progressTracker = createAssistantProgressTracker(assistantMessageId, initialProgress);
1048
1068
  streamProgress = createAssistantStreamProgressHandler(progressTracker);
1049
1069
  assistantContent = '';
@@ -1054,38 +1074,75 @@ function executeAiAssistantCodexRun(payload, context) {
1054
1074
  lastDirective = null;
1055
1075
  toolResponseDebug = null;
1056
1076
  toolError = null;
1057
- _g.label = 1;
1058
- case 1:
1059
- _g.trys.push([1, 30, 31, 32]);
1077
+ termHints = [];
1060
1078
  collectionHints = [];
1061
- _g.label = 2;
1079
+ collectionTokenization = null;
1080
+ collectionRanking = null;
1081
+ collectionSelection = null;
1082
+ timingBreakdown = {
1083
+ directiveMs: 0,
1084
+ initialResponseMs: 0,
1085
+ forcedDirectiveMs: 0,
1086
+ toolMs: 0,
1087
+ followupMs: 0
1088
+ };
1089
+ contextRoute = normalizeOptionalString((_f = input === null || input === void 0 ? void 0 : input.context) === null || _f === void 0 ? void 0 : _f.route);
1090
+ contextMode = normalizeOptionalString((_g = input === null || input === void 0 ? void 0 : input.context) === null || _g === void 0 ? void 0 : _g.mode);
1091
+ recordStep('Queued', { requestId: requestId || undefined });
1092
+ _s.label = 1;
1093
+ case 1:
1094
+ _s.trys.push([1, 30, 31, 32]);
1095
+ hintSeed = [message, contextRoute].filter(Boolean).join(' ');
1096
+ termExpansion = expandAssistantTermSynonyms(hintSeed);
1097
+ hintText = termExpansion.expanded || hintSeed;
1098
+ termHints = termExpansion.matches.map(function (match) { return "".concat(match.term, " -> ").concat(match.expansions.join(', ')); });
1099
+ baseTokens = tokenizeCollectionText(hintSeed);
1100
+ expandedTokens = tokenizeCollectionText(hintText);
1101
+ collectionTokenization = {
1102
+ baseText: hintSeed || undefined,
1103
+ expandedText: hintText || undefined,
1104
+ baseTokens: baseTokens.length ? baseTokens : undefined,
1105
+ expandedTokens: expandedTokens.length ? expandedTokens : undefined
1106
+ };
1107
+ recordStep('Planning: term expansion', {
1108
+ termMatches: termExpansion.matches.length ? termExpansion.matches : undefined
1109
+ });
1110
+ _s.label = 2;
1062
1111
  case 2:
1063
- _g.trys.push([2, 4, , 5]);
1112
+ _s.trys.push([2, 4, , 5]);
1064
1113
  dbName = resolveAssistantDatabaseName(undefined, input.mongo);
1065
1114
  db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
1066
- hintText = [
1067
- message,
1068
- normalizeOptionalString((_f = input === null || input === void 0 ? void 0 : input.context) === null || _f === void 0 ? void 0 : _f.route)
1069
- ].filter(Boolean).join(' ');
1070
- return [4 /*yield*/, resolveAssistantCollectionHints(hintText, dbName, db)];
1115
+ return [4 /*yield*/, listAssistantCollections(db, dbName)];
1071
1116
  case 3:
1072
- collectionHints = _g.sent();
1117
+ collectionNames = _s.sent();
1118
+ collectionHints = resolveCollectionHintsFromTokens(expandedTokens, collectionNames, 5);
1119
+ collectionRanking = buildCollectionRankingDebugFromTokens(expandedTokens, collectionNames, 8);
1073
1120
  return [3 /*break*/, 5];
1074
1121
  case 4:
1075
- _a = _g.sent();
1122
+ _a = _s.sent();
1076
1123
  collectionHints = [];
1124
+ collectionRanking = collectionRanking || ((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens)
1125
+ ? buildCollectionRankingDebugFromTokens(collectionTokenization.expandedTokens || [], [], 0)
1126
+ : null);
1077
1127
  return [3 /*break*/, 5];
1078
1128
  case 5:
1129
+ recordStep('Planning: collection hints', {
1130
+ contextRoute: contextRoute || undefined,
1131
+ contextMode: contextMode || undefined,
1132
+ collectionHints: collectionHints.length ? collectionHints : undefined,
1133
+ termHints: termHints.length ? termHints : undefined
1134
+ });
1079
1135
  assistantContext = buildAssistantContext(input, {
1080
1136
  isSuperAdmin: isSuperAdmin,
1081
1137
  hasInvoiceAccess: hasInvoiceAccess,
1082
1138
  customerId: customerId,
1083
- collectionHints: collectionHints
1139
+ collectionHints: collectionHints,
1140
+ termHints: termHints
1084
1141
  });
1085
1142
  prompt_1 = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1086
1143
  return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
1087
1144
  case 6:
1088
- workspaceRoot = _g.sent();
1145
+ workspaceRoot = _s.sent();
1089
1146
  codexConfig = resolveCodexSettings();
1090
1147
  runOptions = {
1091
1148
  timeoutMs: resolveCodexTimeoutMs(),
@@ -1104,52 +1161,82 @@ function executeAiAssistantCodexRun(payload, context) {
1104
1161
  directiveText = '';
1105
1162
  directive = null;
1106
1163
  if (!dataQuestion) return [3 /*break*/, 10];
1164
+ recordStep('Directive: determine tool', { type: 'data-question' });
1107
1165
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1108
- _g.label = 7;
1166
+ _s.label = 7;
1109
1167
  case 7:
1110
- _g.trys.push([7, 9, , 10]);
1168
+ _s.trys.push([7, 9, , 10]);
1169
+ directiveStart = Date.now();
1111
1170
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1112
1171
  case 8:
1113
- directiveText = _g.sent();
1172
+ directiveText = _s.sent();
1173
+ timingBreakdown.directiveMs = Date.now() - directiveStart;
1114
1174
  forcedDirective = extractAssistantMongoDirective(directiveText);
1115
1175
  if (forcedDirective) {
1116
1176
  directive = forcedDirective;
1117
1177
  directiveSource = 'model';
1118
1178
  lastDirective = forcedDirective;
1179
+ collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((_h = directive.payload) === null || _h === void 0 ? void 0 : _h.collection) || '');
1180
+ recordStep('Directive resolved', {
1181
+ source: directiveSource,
1182
+ type: directive.type,
1183
+ collection: normalizeOptionalString((_j = directive.payload) === null || _j === void 0 ? void 0 : _j.collection) || undefined,
1184
+ permissionView: normalizeOptionalString((_k = directive.payload) === null || _k === void 0 ? void 0 : _k.permissionView) || undefined
1185
+ });
1119
1186
  }
1120
1187
  return [3 /*break*/, 10];
1121
1188
  case 9:
1122
- _b = _g.sent();
1189
+ _b = _s.sent();
1123
1190
  return [3 /*break*/, 10];
1124
1191
  case 10:
1125
1192
  if (!!directive) return [3 /*break*/, 12];
1193
+ recordStep('Response: draft initial answer', { mode: 'full' });
1194
+ initialStart = Date.now();
1126
1195
  return [4 /*yield*/, runCodexInWorkerThread(prompt_1, runOptions, codexConfig, streamProgress)];
1127
1196
  case 11:
1128
- responseText = _g.sent();
1197
+ responseText = _s.sent();
1198
+ timingBreakdown.initialResponseMs = Date.now() - initialStart;
1129
1199
  directive = extractAssistantMongoDirective(responseText);
1130
1200
  if (directive) {
1131
1201
  directiveSource = 'model';
1132
1202
  lastDirective = directive;
1203
+ collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((_l = directive.payload) === null || _l === void 0 ? void 0 : _l.collection) || '');
1204
+ recordStep('Directive resolved', {
1205
+ source: directiveSource,
1206
+ type: directive.type,
1207
+ collection: normalizeOptionalString((_m = directive.payload) === null || _m === void 0 ? void 0 : _m.collection) || undefined,
1208
+ permissionView: normalizeOptionalString((_o = directive.payload) === null || _o === void 0 ? void 0 : _o.permissionView) || undefined
1209
+ });
1133
1210
  }
1134
- _g.label = 12;
1211
+ _s.label = 12;
1135
1212
  case 12:
1136
1213
  if (!(!directive && dataQuestion)) return [3 /*break*/, 16];
1214
+ recordStep('Directive: forced retry', { mode: 'directive-only' });
1137
1215
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1138
- _g.label = 13;
1216
+ _s.label = 13;
1139
1217
  case 13:
1140
- _g.trys.push([13, 15, , 16]);
1218
+ _s.trys.push([13, 15, , 16]);
1219
+ forcedStart = Date.now();
1141
1220
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1142
1221
  case 14:
1143
- directiveText = _g.sent();
1222
+ directiveText = _s.sent();
1223
+ timingBreakdown.forcedDirectiveMs = Date.now() - forcedStart;
1144
1224
  forcedDirective = extractAssistantMongoDirective(directiveText);
1145
1225
  if (forcedDirective) {
1146
1226
  directive = forcedDirective;
1147
1227
  directiveSource = 'forced';
1148
1228
  lastDirective = forcedDirective;
1229
+ collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((_p = directive.payload) === null || _p === void 0 ? void 0 : _p.collection) || '');
1230
+ recordStep('Directive resolved', {
1231
+ source: directiveSource,
1232
+ type: directive.type,
1233
+ collection: normalizeOptionalString((_q = directive.payload) === null || _q === void 0 ? void 0 : _q.collection) || undefined,
1234
+ permissionView: normalizeOptionalString((_r = directive.payload) === null || _r === void 0 ? void 0 : _r.permissionView) || undefined
1235
+ });
1149
1236
  }
1150
1237
  return [3 /*break*/, 16];
1151
1238
  case 15:
1152
- _c = _g.sent();
1239
+ _c = _s.sent();
1153
1240
  return [3 /*break*/, 16];
1154
1241
  case 16:
1155
1242
  cleanedResponseText = (directive === null || directive === void 0 ? void 0 : directive.cleaned) || responseText;
@@ -1159,53 +1246,70 @@ function executeAiAssistantCodexRun(payload, context) {
1159
1246
  if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 28];
1160
1247
  toolRequest = buildAssistantToolRequest(directive, input);
1161
1248
  progressTracker.push('Grabbing Data');
1162
- _g.label = 17;
1249
+ recordStep('Grabbing Data: start', {
1250
+ type: directive.type,
1251
+ collection: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.collection) || undefined,
1252
+ permissionView: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.permissionView) || undefined
1253
+ });
1254
+ _s.label = 17;
1163
1255
  case 17:
1164
- _g.trys.push([17, 26, , 27]);
1256
+ _s.trys.push([17, 26, , 27]);
1257
+ toolStart = Date.now();
1165
1258
  if (!(directive.type === 'aggregate')) return [3 /*break*/, 19];
1166
1259
  return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
1167
1260
  case 18:
1168
- _d = _g.sent();
1261
+ _d = _s.sent();
1169
1262
  return [3 /*break*/, 21];
1170
1263
  case 19: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
1171
1264
  case 20:
1172
- _d = _g.sent();
1173
- _g.label = 21;
1265
+ _d = _s.sent();
1266
+ _s.label = 21;
1174
1267
  case 21:
1175
1268
  toolResponse = _d;
1269
+ timingBreakdown.toolMs = Date.now() - toolStart;
1176
1270
  toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
1177
1271
  ? toolResponse.debug
1178
1272
  : null;
1179
1273
  toolPayload = buildAssistantToolResultPayload(directive, toolResponse);
1180
1274
  toolResult = toolPayload.result;
1275
+ recordStep('Grabbing Data: complete', {
1276
+ rowCount: toolPayload.result.output.rowCount,
1277
+ total: toolPayload.result.output.total,
1278
+ columns: toolPayload.result.output.columns
1279
+ });
1181
1280
  progressTracker.push('Drafting response');
1281
+ recordStep('Drafting response');
1182
1282
  followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
1183
- _g.label = 22;
1283
+ _s.label = 22;
1184
1284
  case 22:
1185
- _g.trys.push([22, 24, , 25]);
1285
+ _s.trys.push([22, 24, , 25]);
1286
+ followupStart = Date.now();
1186
1287
  return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
1187
1288
  case 23:
1188
- followupText = _g.sent();
1289
+ followupText = _s.sent();
1290
+ timingBreakdown.followupMs = Date.now() - followupStart;
1189
1291
  assistantContent = sanitizeAssistantResponse(followupText);
1190
1292
  return [3 /*break*/, 25];
1191
1293
  case 24:
1192
- _e = _g.sent();
1294
+ _e = _s.sent();
1193
1295
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
1194
1296
  return [3 /*break*/, 25];
1195
1297
  case 25: return [3 /*break*/, 27];
1196
1298
  case 26:
1197
- error_2 = _g.sent();
1299
+ error_2 = _s.sent();
1198
1300
  assistantContent = buildAssistantToolErrorMessage(error_2, directive, toolRequest);
1199
1301
  toolError = error_2;
1200
1302
  return [3 /*break*/, 27];
1201
1303
  case 27: return [3 /*break*/, 29];
1202
1304
  case 28:
1203
1305
  progressTracker.push('Drafting response');
1204
- _g.label = 29;
1306
+ recordStep('Drafting response');
1307
+ _s.label = 29;
1205
1308
  case 29: return [3 /*break*/, 32];
1206
1309
  case 30:
1207
- error_3 = _g.sent();
1310
+ error_3 = _s.sent();
1208
1311
  assistantContent = buildAssistantCodexErrorMessage(error_3);
1312
+ recordStep('Error', { message: normalizeOptionalString(error_3 === null || error_3 === void 0 ? void 0 : error_3.message) || 'Unknown error' });
1209
1313
  return [3 /*break*/, 32];
1210
1314
  case 31:
1211
1315
  progressTracker.stop();
@@ -1216,13 +1320,43 @@ function executeAiAssistantCodexRun(payload, context) {
1216
1320
  }
1217
1321
  finalNow = new Date();
1218
1322
  if (isSuperAdmin) {
1323
+ finishedAt = Date.now();
1324
+ codexMs = timingBreakdown.directiveMs
1325
+ + timingBreakdown.initialResponseMs
1326
+ + timingBreakdown.forcedDirectiveMs
1327
+ + timingBreakdown.followupMs;
1328
+ draftingMs = timingBreakdown.followupMs || timingBreakdown.initialResponseMs;
1219
1329
  assistantDebug = buildAssistantDebugPayload({
1220
1330
  dataQuestion: dataQuestion,
1221
1331
  directive: lastDirective,
1222
1332
  directiveSource: directiveSource,
1223
1333
  toolResult: toolResult,
1224
1334
  toolResponseDebug: toolResponseDebug,
1225
- toolError: toolError
1335
+ toolError: toolError,
1336
+ trace: {
1337
+ steps: steps,
1338
+ planning: {
1339
+ contextMode: contextMode || undefined,
1340
+ contextRoute: contextRoute || undefined,
1341
+ termHints: termHints.length ? termHints : undefined,
1342
+ collectionHints: collectionHints.length ? collectionHints : undefined,
1343
+ collectionTokenization: collectionTokenization || undefined,
1344
+ collectionRanking: collectionRanking || undefined,
1345
+ collectionSelection: collectionSelection || undefined
1346
+ },
1347
+ timings: {
1348
+ startedAt: new Date(runStart).toISOString(),
1349
+ finishedAt: new Date(finishedAt).toISOString(),
1350
+ totalMs: finishedAt - runStart,
1351
+ codexMs: codexMs,
1352
+ draftingMs: draftingMs,
1353
+ toolMs: timingBreakdown.toolMs,
1354
+ directiveMs: timingBreakdown.directiveMs,
1355
+ initialResponseMs: timingBreakdown.initialResponseMs,
1356
+ forcedDirectiveMs: timingBreakdown.forcedDirectiveMs,
1357
+ followupMs: timingBreakdown.followupMs
1358
+ }
1359
+ }
1226
1360
  });
1227
1361
  }
1228
1362
  finalMetadata = __assign(__assign(__assign({ model: resolveCodexModel() }, (requestId ? { request_id: requestId } : {})), (toolResult ? { tool_result: toolResult } : {})), (assistantDebug ? { debug: assistantDebug } : {}));
@@ -1236,16 +1370,16 @@ function executeAiAssistantCodexRun(payload, context) {
1236
1370
  }
1237
1371
  })];
1238
1372
  case 33:
1239
- _g.sent();
1240
- _g.label = 34;
1373
+ _s.sent();
1374
+ _s.label = 34;
1241
1375
  case 34: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
1242
1376
  case 35:
1243
- _g.sent();
1377
+ _s.sent();
1244
1378
  if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 37];
1245
1379
  return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
1246
1380
  case 36:
1247
- _g.sent();
1248
- _g.label = 37;
1381
+ _s.sent();
1382
+ _s.label = 37;
1249
1383
  case 37: return [2 /*return*/, finalAssistantDoc];
1250
1384
  }
1251
1385
  });
@@ -1259,7 +1393,7 @@ function executeAiAssistantCodexRun(payload, context) {
1259
1393
  }
1260
1394
  function executeAiAssistantMongoRead(payload, context) {
1261
1395
  return __awaiter(this, void 0, void 0, function () {
1262
- var input, rawCollection, dbName, db, collectionResolution, collection, _a, user, isSuperAdmin, customerId, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalized, findOptions, documents, executedQuery, fallbackMeta, dateFallback, fallbackQuery, fallbackDocs, total, sanitizedDocuments, includeIds, display;
1396
+ var input, rawCollection, dbName, db, collectionResolution, collection, _a, user, isSuperAdmin, customerId, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalized, findOptions, documents, executedQuery, fallbackMeta, dateFallback, fallbackQuery, fallbackDocs, expanded, fallbackDocs, total, sanitizedDocuments, includeIds, requestedFields, fieldAliases, displayDocs, priorityFields, display;
1263
1397
  var _c, _d;
1264
1398
  return __generator(this, function (_e) {
1265
1399
  switch (_e.label) {
@@ -1314,7 +1448,7 @@ function executeAiAssistantMongoRead(payload, context) {
1314
1448
  documents = _e.sent();
1315
1449
  executedQuery = scopedQuery;
1316
1450
  fallbackMeta = {};
1317
- if (!!documents.length) return [3 /*break*/, 8];
1451
+ if (!!documents.length) return [3 /*break*/, 10];
1318
1452
  dateFallback = resolveQueryDateFieldFallback(scopedQuery);
1319
1453
  if (!dateFallback) return [3 /*break*/, 8];
1320
1454
  fallbackQuery = replaceQueryField(scopedQuery, dateFallback.from, dateFallback.to);
@@ -1329,25 +1463,55 @@ function executeAiAssistantMongoRead(payload, context) {
1329
1463
  }
1330
1464
  _e.label = 8;
1331
1465
  case 8:
1332
- total = null;
1333
- if (!normalized.includeTotal) return [3 /*break*/, 10];
1334
- return [4 /*yield*/, db.collection(collection).countDocuments(executedQuery, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
1466
+ if (!!documents.length) return [3 /*break*/, 10];
1467
+ expanded = expandQueryDateFallbacks(scopedQuery);
1468
+ if (!expanded) return [3 /*break*/, 10];
1469
+ fallbackMeta.dateFieldsExpanded = {
1470
+ fields: expanded.fields,
1471
+ attempted: true,
1472
+ used: false
1473
+ };
1474
+ return [4 /*yield*/, db.collection(collection).find(expanded.query, findOptions).toArray()];
1335
1475
  case 9:
1336
- total = _e.sent();
1476
+ fallbackDocs = _e.sent();
1477
+ if (fallbackDocs.length) {
1478
+ documents = fallbackDocs;
1479
+ executedQuery = expanded.query;
1480
+ fallbackMeta.dateFieldsExpanded.used = true;
1481
+ }
1337
1482
  _e.label = 10;
1338
1483
  case 10:
1484
+ total = null;
1485
+ if (!normalized.includeTotal) return [3 /*break*/, 12];
1486
+ return [4 /*yield*/, db.collection(collection).countDocuments(executedQuery, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
1487
+ case 11:
1488
+ total = _e.sent();
1489
+ _e.label = 12;
1490
+ case 12:
1339
1491
  sanitizedDocuments = isSuperAdmin
1340
1492
  ? documents
1341
1493
  : documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
1342
1494
  includeIds = ((_d = input.options) === null || _d === void 0 ? void 0 : _d.includeIds) === true;
1343
- display = buildDisplayTable(sanitizedDocuments, {
1495
+ requestedFields = resolveProjectionRequestedFields(normalized.findOptions.projection);
1496
+ fieldAliases = resolveFieldAliases(sanitizedDocuments, requestedFields);
1497
+ displayDocs = Object.keys(fieldAliases).length
1498
+ ? applyFieldAliasesForDisplay(sanitizedDocuments, fieldAliases)
1499
+ : sanitizedDocuments;
1500
+ priorityFields = requestedFields.length
1501
+ ? __spreadArray(__spreadArray([], __read(requestedFields), false), __read(AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS), false) : AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS;
1502
+ display = buildDisplayTable(displayDocs, {
1344
1503
  includeIds: includeIds,
1345
1504
  maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
1346
- maxRows: normalized.findOptions.limit
1505
+ maxRows: normalized.findOptions.limit,
1506
+ priorityFields: priorityFields,
1507
+ includeGroupFromId: false
1347
1508
  });
1348
1509
  if (total !== null) {
1349
1510
  display.total = total;
1350
1511
  }
1512
+ if (Object.keys(fieldAliases).length) {
1513
+ fallbackMeta.fieldAliases = fieldAliases;
1514
+ }
1351
1515
  return [2 /*return*/, __assign({ documents: sanitizedDocuments, total: total, display: display }, (isSuperAdmin ? {
1352
1516
  debug: {
1353
1517
  collection: collection,
@@ -1369,7 +1533,7 @@ function executeAiAssistantMongoRead(payload, context) {
1369
1533
  }
1370
1534
  function executeAiAssistantMongoAggregate(payload, context) {
1371
1535
  return __awaiter(this, void 0, void 0, function () {
1372
- var input, rawCollection, dbName, db, collectionResolution, collection, _a, user, isSuperAdmin, customerId, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, dateField, aggregateOptions, documents, executedPipeline, fallbackMeta, fallback, fallbackPipeline, fallbackDocs, createdFallback, createdPipeline, createdDocs, completionFallback, fallbackPipeline, fallbackDocs, unwindFallback, fallbackPipeline, fallbackDocs, sanitizedDocuments, includeIds, display;
1536
+ var input, rawCollection, dbName, db, collectionResolution, collection, _a, user, isSuperAdmin, customerId, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, dateField, aggregateOptions, documents, executedPipeline, fallbackMeta, fallback, fallbackPipeline, fallbackDocs, createdFallback, createdPipeline, createdDocs, completionFallback, fallbackPipeline, fallbackDocs, completionExprFallback, fallbackPipeline, fallbackDocs, unwindFallback, fallbackPipeline, fallbackDocs, nameFallback, fallbackPipeline, fallbackDocs, sanitizedDocuments, includeIds, display;
1373
1537
  var _c, _d;
1374
1538
  return __generator(this, function (_e) {
1375
1539
  switch (_e.label) {
@@ -1468,7 +1632,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
1468
1632
  }
1469
1633
  _e.label = 10;
1470
1634
  case 10:
1471
- if (!!documents.length) return [3 /*break*/, 12];
1635
+ if (!!documents.length) return [3 /*break*/, 14];
1472
1636
  completionFallback = resolveAggregateCompletionFallback(executedPipeline);
1473
1637
  if (!completionFallback) return [3 /*break*/, 12];
1474
1638
  fallbackMeta.completion = {
@@ -1476,7 +1640,8 @@ function executeAiAssistantMongoAggregate(payload, context) {
1476
1640
  sources: completionFallback.sources,
1477
1641
  attempted: true,
1478
1642
  used: false,
1479
- statusFilter: !!completionFallback.statusFilter
1643
+ statusFilter: !!completionFallback.statusFilter,
1644
+ strategy: 'addFields'
1480
1645
  };
1481
1646
  fallbackPipeline = buildAggregateCompletionFallbackPipeline(executedPipeline, completionFallback);
1482
1647
  if (!(fallbackPipeline.length && !containsForbiddenMongoOperators(fallbackPipeline))) return [3 /*break*/, 12];
@@ -1492,24 +1657,72 @@ function executeAiAssistantMongoAggregate(payload, context) {
1492
1657
  }
1493
1658
  _e.label = 12;
1494
1659
  case 12:
1495
- if (!(documents.length <= 1)) return [3 /*break*/, 14];
1660
+ if (!!documents.length) return [3 /*break*/, 14];
1661
+ completionExprFallback = resolveAggregateCompletionExprFallback(executedPipeline);
1662
+ if (!completionExprFallback) return [3 /*break*/, 14];
1663
+ fallbackMeta.completion = {
1664
+ field: completionExprFallback.field,
1665
+ sources: completionExprFallback.sources,
1666
+ attempted: true,
1667
+ used: false,
1668
+ statusFilter: !!completionExprFallback.statusFilter,
1669
+ strategy: 'expr'
1670
+ };
1671
+ fallbackPipeline = buildAggregateCompletionExprFallbackPipeline(executedPipeline, completionExprFallback);
1672
+ if (!(fallbackPipeline.length && !containsForbiddenMongoOperators(fallbackPipeline))) return [3 /*break*/, 14];
1673
+ return [4 /*yield*/, db.collection(collection)
1674
+ .aggregate(fallbackPipeline, aggregateOptions)
1675
+ .toArray()];
1676
+ case 13:
1677
+ fallbackDocs = _e.sent();
1678
+ if (fallbackDocs.length) {
1679
+ documents = fallbackDocs;
1680
+ executedPipeline = fallbackPipeline;
1681
+ fallbackMeta.completion.used = true;
1682
+ }
1683
+ _e.label = 14;
1684
+ case 14:
1685
+ if (!(documents.length <= 1)) return [3 /*break*/, 16];
1496
1686
  unwindFallback = resolveAggregateUnwindFallback(executedPipeline);
1497
- if (!unwindFallback) return [3 /*break*/, 14];
1687
+ if (!unwindFallback) return [3 /*break*/, 16];
1498
1688
  fallbackMeta.unwind = { path: unwindFallback.path, attempted: true, used: false };
1499
1689
  fallbackPipeline = buildAggregateUnwindFallbackPipeline(executedPipeline, unwindFallback);
1500
- if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/, 14];
1690
+ if (!!containsForbiddenMongoOperators(fallbackPipeline)) return [3 /*break*/, 16];
1501
1691
  return [4 /*yield*/, db.collection(collection)
1502
1692
  .aggregate(fallbackPipeline, aggregateOptions)
1503
1693
  .toArray()];
1504
- case 13:
1694
+ case 15:
1505
1695
  fallbackDocs = _e.sent();
1506
1696
  if (fallbackDocs.length > documents.length) {
1507
1697
  documents = fallbackDocs;
1508
1698
  executedPipeline = fallbackPipeline;
1509
1699
  fallbackMeta.unwind.used = true;
1510
1700
  }
1511
- _e.label = 14;
1512
- case 14:
1701
+ _e.label = 16;
1702
+ case 16:
1703
+ if (!!documents.length) return [3 /*break*/, 18];
1704
+ nameFallback = resolveAggregateNameMatchFallback(executedPipeline);
1705
+ if (!nameFallback) return [3 /*break*/, 18];
1706
+ fallbackMeta.nameMatch = {
1707
+ field: nameFallback.field,
1708
+ fields: nameFallback.fields,
1709
+ attempted: true,
1710
+ used: false
1711
+ };
1712
+ fallbackPipeline = buildAggregateNameMatchFallbackPipeline(executedPipeline, nameFallback);
1713
+ if (!(fallbackPipeline.length && !containsForbiddenMongoOperators(fallbackPipeline))) return [3 /*break*/, 18];
1714
+ return [4 /*yield*/, db.collection(collection)
1715
+ .aggregate(fallbackPipeline, aggregateOptions)
1716
+ .toArray()];
1717
+ case 17:
1718
+ fallbackDocs = _e.sent();
1719
+ if (fallbackDocs.length) {
1720
+ documents = fallbackDocs;
1721
+ executedPipeline = fallbackPipeline;
1722
+ fallbackMeta.nameMatch.used = true;
1723
+ }
1724
+ _e.label = 18;
1725
+ case 18:
1513
1726
  sanitizedDocuments = isSuperAdmin
1514
1727
  ? documents
1515
1728
  : documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
@@ -1517,7 +1730,8 @@ function executeAiAssistantMongoAggregate(payload, context) {
1517
1730
  display = buildDisplayTable(sanitizedDocuments, {
1518
1731
  includeIds: includeIds,
1519
1732
  maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
1520
- maxRows: normalizedOptions.limit || sanitizedDocuments.length
1733
+ maxRows: normalizedOptions.limit || sanitizedDocuments.length,
1734
+ includeGroupFromId: true
1521
1735
  });
1522
1736
  return [2 /*return*/, __assign({ documents: sanitizedDocuments, display: display }, (isSuperAdmin ? {
1523
1737
  debug: {
@@ -1606,7 +1820,8 @@ function buildAssistantToolResultPayload(directive, toolResponse) {
1606
1820
  : buildDisplayTable(documents, {
1607
1821
  includeIds: includeIds,
1608
1822
  maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
1609
- maxRows: AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS
1823
+ maxRows: AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS,
1824
+ includeGroupFromId: directive.type === 'aggregate'
1610
1825
  });
1611
1826
  var trimmedDisplay = trimDisplayTable(display, {
1612
1827
  maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
@@ -1686,7 +1901,7 @@ function buildAssistantToolFallbackResponse(result) {
1686
1901
  return lines.join('\n').trim();
1687
1902
  }
1688
1903
  function buildAssistantDebugPayload(params) {
1689
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
1904
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
1690
1905
  var notes = [];
1691
1906
  if (params.dataQuestion) {
1692
1907
  notes.push('Detected a data request; tool call required.');
@@ -1727,16 +1942,37 @@ function buildAssistantDebugPayload(params) {
1727
1942
  if ((_k = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateFieldCreatedAt) === null || _k === void 0 ? void 0 : _k.used) {
1728
1943
  notes.push("Retried with date field fallback ".concat(fallbackInfo.dateFieldCreatedAt.from, " -> ").concat(fallbackInfo.dateFieldCreatedAt.to, "."));
1729
1944
  }
1730
- if ((_l = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.unwind) === null || _l === void 0 ? void 0 : _l.used) {
1945
+ if ((_l = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.completion) === null || _l === void 0 ? void 0 : _l.used) {
1946
+ var sources = Array.isArray(fallbackInfo.completion.sources)
1947
+ ? fallbackInfo.completion.sources.join(', ')
1948
+ : fallbackInfo.completion.field;
1949
+ var strategy = fallbackInfo.completion.strategy ? " (".concat(fallbackInfo.completion.strategy, ")") : '';
1950
+ notes.push("Applied completion fallback".concat(strategy, ": ").concat(sources, "."));
1951
+ }
1952
+ if ((_m = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.dateFieldsExpanded) === null || _m === void 0 ? void 0 : _m.used) {
1953
+ var fields = Array.isArray(fallbackInfo.dateFieldsExpanded.fields)
1954
+ ? fallbackInfo.dateFieldsExpanded.fields.join(', ')
1955
+ : String(fallbackInfo.dateFieldsExpanded.fields || '');
1956
+ if (fields) {
1957
+ notes.push("Expanded date fields: ".concat(fields, "."));
1958
+ }
1959
+ }
1960
+ if ((_o = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.unwind) === null || _o === void 0 ? void 0 : _o.used) {
1731
1961
  notes.push("Applied unwind fallback on ".concat(fallbackInfo.unwind.path, "."));
1732
1962
  }
1963
+ if ((_p = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.nameMatch) === null || _p === void 0 ? void 0 : _p.used) {
1964
+ var fields = Array.isArray(fallbackInfo.nameMatch.fields)
1965
+ ? fallbackInfo.nameMatch.fields.join(', ')
1966
+ : fallbackInfo.nameMatch.field;
1967
+ notes.push("Expanded name match fields: ".concat(fields, "."));
1968
+ }
1733
1969
  if (params.toolError) {
1734
- var errorMessage = ((_m = params.toolError) === null || _m === void 0 ? void 0 : _m.message) || String(params.toolError || '');
1970
+ var errorMessage = ((_q = params.toolError) === null || _q === void 0 ? void 0 : _q.message) || String(params.toolError || '');
1735
1971
  if (errorMessage) {
1736
1972
  notes.push("Tool error: ".concat(errorMessage));
1737
1973
  }
1738
1974
  }
1739
- return {
1975
+ var payload = {
1740
1976
  decision: {
1741
1977
  dataQuestion: params.dataQuestion,
1742
1978
  directiveSource: params.directiveSource
@@ -1751,15 +1987,19 @@ function buildAssistantDebugPayload(params) {
1751
1987
  collectionResolved: resolvedCollection || undefined,
1752
1988
  collectionMatched: matchedCollection,
1753
1989
  collectionCandidates: candidateCollections.length ? candidateCollections : undefined,
1754
- collectionScore: typeof ((_o = params.toolResponseDebug) === null || _o === void 0 ? void 0 : _o.collectionScore) === 'number'
1990
+ collectionScore: typeof ((_r = params.toolResponseDebug) === null || _r === void 0 ? void 0 : _r.collectionScore) === 'number'
1755
1991
  ? params.toolResponseDebug.collectionScore
1756
1992
  : undefined,
1757
- query: ((_p = params.toolResponseDebug) === null || _p === void 0 ? void 0 : _p.query) || undefined,
1758
- pipeline: ((_q = params.toolResponseDebug) === null || _q === void 0 ? void 0 : _q.executedPipeline) || ((_r = params.toolResponseDebug) === null || _r === void 0 ? void 0 : _r.originalPipeline) || undefined,
1759
- options: ((_s = params.toolResponseDebug) === null || _s === void 0 ? void 0 : _s.options) || undefined,
1760
- fallbacks: ((_t = params.toolResponseDebug) === null || _t === void 0 ? void 0 : _t.fallbacks) || undefined,
1993
+ query: ((_s = params.toolResponseDebug) === null || _s === void 0 ? void 0 : _s.query) || undefined,
1994
+ pipeline: ((_t = params.toolResponseDebug) === null || _t === void 0 ? void 0 : _t.executedPipeline) || ((_u = params.toolResponseDebug) === null || _u === void 0 ? void 0 : _u.originalPipeline) || undefined,
1995
+ options: ((_v = params.toolResponseDebug) === null || _v === void 0 ? void 0 : _v.options) || undefined,
1996
+ fallbacks: ((_w = params.toolResponseDebug) === null || _w === void 0 ? void 0 : _w.fallbacks) || undefined,
1761
1997
  notes: notes
1762
1998
  };
1999
+ if (params.trace && typeof params.trace === 'object') {
2000
+ payload.trace = params.trace;
2001
+ }
2002
+ return payload;
1763
2003
  }
1764
2004
  function buildAssistantToolErrorMessage(error, directive, request) {
1765
2005
  var _a, _b;
@@ -2009,6 +2249,219 @@ function normalizeColumnPriorityKey(column) {
2009
2249
  var base = trimmed.includes('.') ? trimmed.split('.').pop() || trimmed : trimmed;
2010
2250
  return base.toLowerCase();
2011
2251
  }
2252
+ function tokenizeFieldKey(value) {
2253
+ var normalized = String(value || '')
2254
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
2255
+ .replace(/[^a-zA-Z0-9]+/g, ' ')
2256
+ .trim()
2257
+ .toLowerCase();
2258
+ return normalized ? normalized.split(/\s+/).filter(Boolean) : [];
2259
+ }
2260
+ function normalizeFieldMatchKey(value) {
2261
+ return tokenizeFieldKey(value).join('');
2262
+ }
2263
+ function getValueAtPath(obj, path) {
2264
+ var e_1, _a;
2265
+ if (!obj || typeof obj !== 'object') {
2266
+ return undefined;
2267
+ }
2268
+ var parts = String(path || '').split('.').filter(Boolean);
2269
+ var current = obj;
2270
+ try {
2271
+ for (var parts_1 = __values(parts), parts_1_1 = parts_1.next(); !parts_1_1.done; parts_1_1 = parts_1.next()) {
2272
+ var part = parts_1_1.value;
2273
+ if (!current || typeof current !== 'object') {
2274
+ return undefined;
2275
+ }
2276
+ current = current[part];
2277
+ }
2278
+ }
2279
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2280
+ finally {
2281
+ try {
2282
+ if (parts_1_1 && !parts_1_1.done && (_a = parts_1.return)) _a.call(parts_1);
2283
+ }
2284
+ finally { if (e_1) throw e_1.error; }
2285
+ }
2286
+ return current;
2287
+ }
2288
+ function hasNonEmptyValue(docs, fieldPath, options) {
2289
+ var e_2, _a;
2290
+ if (!Array.isArray(docs) || !fieldPath) {
2291
+ return false;
2292
+ }
2293
+ var usePath = fieldPath.includes('.');
2294
+ try {
2295
+ for (var docs_1 = __values(docs), docs_1_1 = docs_1.next(); !docs_1_1.done; docs_1_1 = docs_1.next()) {
2296
+ var doc = docs_1_1.value;
2297
+ var value = usePath ? getValueAtPath(doc, fieldPath) : doc === null || doc === void 0 ? void 0 : doc[fieldPath];
2298
+ if ((options === null || options === void 0 ? void 0 : options.treatObjectLikeAsEmpty) && isDisplayObjectLike(value)) {
2299
+ continue;
2300
+ }
2301
+ if (!isEmptyDisplayValue(value)) {
2302
+ return true;
2303
+ }
2304
+ }
2305
+ }
2306
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
2307
+ finally {
2308
+ try {
2309
+ if (docs_1_1 && !docs_1_1.done && (_a = docs_1.return)) _a.call(docs_1);
2310
+ }
2311
+ finally { if (e_2) throw e_2.error; }
2312
+ }
2313
+ return false;
2314
+ }
2315
+ function collectFieldCandidates(docs) {
2316
+ var candidates = new Map();
2317
+ if (!Array.isArray(docs)) {
2318
+ return candidates;
2319
+ }
2320
+ var addCandidate = function (path, value) {
2321
+ if (!path) {
2322
+ return;
2323
+ }
2324
+ var entry = candidates.get(path) || {
2325
+ nonEmpty: 0,
2326
+ objectLike: 0,
2327
+ normalized: normalizeFieldMatchKey(path)
2328
+ };
2329
+ if (!isEmptyDisplayValue(value)) {
2330
+ entry.nonEmpty += 1;
2331
+ }
2332
+ if (isDisplayObjectLike(value)) {
2333
+ entry.objectLike += 1;
2334
+ }
2335
+ candidates.set(path, entry);
2336
+ };
2337
+ docs.forEach(function (doc) {
2338
+ if (!doc || typeof doc !== 'object') {
2339
+ return;
2340
+ }
2341
+ Object.keys(doc).forEach(function (key) {
2342
+ if (!key) {
2343
+ return;
2344
+ }
2345
+ var value = doc[key];
2346
+ addCandidate(key, value);
2347
+ if (isPlainObject(value) && !isMongoObjectId(value) && !(value instanceof Date)) {
2348
+ var nestedKeys = Object.keys(value).slice(0, 50);
2349
+ nestedKeys.forEach(function (nestedKey) {
2350
+ if (!nestedKey) {
2351
+ return;
2352
+ }
2353
+ addCandidate("".concat(key, ".").concat(nestedKey), value[nestedKey]);
2354
+ });
2355
+ }
2356
+ });
2357
+ });
2358
+ return candidates;
2359
+ }
2360
+ function resolveFieldAliases(docs, requestedFields) {
2361
+ var aliases = {};
2362
+ if (!Array.isArray(docs) || !requestedFields.length) {
2363
+ return aliases;
2364
+ }
2365
+ var missing = requestedFields.filter(function (field) { return field && !hasNonEmptyValue(docs, field, { treatObjectLikeAsEmpty: true }); });
2366
+ if (!missing.length) {
2367
+ return aliases;
2368
+ }
2369
+ var candidates = collectFieldCandidates(docs);
2370
+ missing.forEach(function (field) {
2371
+ var normalizedRequested = normalizeFieldMatchKey(field);
2372
+ if (!normalizedRequested) {
2373
+ return;
2374
+ }
2375
+ var bestPath = '';
2376
+ var bestScore = 0;
2377
+ candidates.forEach(function (stats, path) {
2378
+ if (!path || stats.nonEmpty === 0) {
2379
+ return;
2380
+ }
2381
+ if (isAssistantIdField(path)) {
2382
+ return;
2383
+ }
2384
+ var normalizedCandidate = stats.normalized || normalizeFieldMatchKey(path);
2385
+ if (!normalizedCandidate) {
2386
+ return;
2387
+ }
2388
+ var score = 0;
2389
+ if (normalizedCandidate === normalizedRequested) {
2390
+ score = 100;
2391
+ }
2392
+ else if (normalizedCandidate.includes(normalizedRequested) || normalizedRequested.includes(normalizedCandidate)) {
2393
+ score = 70;
2394
+ }
2395
+ else {
2396
+ var candidateTokens_1 = tokenizeFieldKey(path);
2397
+ var requestedTokens = tokenizeFieldKey(field);
2398
+ var overlap = requestedTokens.filter(function (token) { return candidateTokens_1.includes(token); }).length;
2399
+ if (overlap > 0) {
2400
+ score = 40 + overlap * 5;
2401
+ }
2402
+ }
2403
+ var objectRatio = stats.objectLike / Math.max(stats.nonEmpty, 1);
2404
+ if (objectRatio > 0.5) {
2405
+ score -= 50;
2406
+ }
2407
+ if (score > bestScore) {
2408
+ bestScore = score;
2409
+ bestPath = path;
2410
+ }
2411
+ });
2412
+ if (bestPath && bestScore >= 60) {
2413
+ aliases[field] = bestPath;
2414
+ }
2415
+ });
2416
+ return aliases;
2417
+ }
2418
+ function applyFieldAliasesForDisplay(docs, aliases) {
2419
+ if (!Array.isArray(docs) || !aliases || !Object.keys(aliases).length) {
2420
+ return docs;
2421
+ }
2422
+ return docs.map(function (doc) {
2423
+ var next = __assign({}, doc);
2424
+ Object.keys(aliases).forEach(function (targetField) {
2425
+ var sourcePath = aliases[targetField];
2426
+ if (!sourcePath) {
2427
+ return;
2428
+ }
2429
+ var existing = targetField.includes('.') ? getValueAtPath(doc, targetField) : doc === null || doc === void 0 ? void 0 : doc[targetField];
2430
+ if (!isEmptyDisplayValue(existing)) {
2431
+ return;
2432
+ }
2433
+ var value = getValueAtPath(doc, sourcePath);
2434
+ if (value !== undefined) {
2435
+ next[targetField] = value;
2436
+ }
2437
+ });
2438
+ return next;
2439
+ });
2440
+ }
2441
+ function resolveProjectionRequestedFields(projection) {
2442
+ if (!projection || typeof projection !== 'object') {
2443
+ return [];
2444
+ }
2445
+ var keys = Object.keys(projection);
2446
+ if (!keys.length) {
2447
+ return [];
2448
+ }
2449
+ var hasInclude = false;
2450
+ var hasExclude = false;
2451
+ keys.forEach(function (key) {
2452
+ var value = projection[key];
2453
+ if (value === 0 || value === false) {
2454
+ hasExclude = true;
2455
+ }
2456
+ else if (value === 1 || value === true) {
2457
+ hasInclude = true;
2458
+ }
2459
+ });
2460
+ if (!hasInclude || hasExclude) {
2461
+ return [];
2462
+ }
2463
+ return keys.filter(function (key) { return !isAssistantIdField(key); });
2464
+ }
2012
2465
  function formatDisplayColumnName(column) {
2013
2466
  var trimmed = String(column || '').trim();
2014
2467
  if (!trimmed) {
@@ -2027,7 +2480,22 @@ function formatDisplayColumnName(column) {
2027
2480
  if (normalized === 'updatedat') {
2028
2481
  return 'Updated At';
2029
2482
  }
2030
- return trimmed;
2483
+ var parts = trimmed.split('.');
2484
+ var base = parts[parts.length - 1] || trimmed;
2485
+ if ((base === 'name' || base === 'title' || base === 'label') && parts.length > 1) {
2486
+ return parts[parts.length - 2]
2487
+ .replace(/[_-]+/g, ' ')
2488
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
2489
+ .replace(/\s+/g, ' ')
2490
+ .trim()
2491
+ .replace(/\b\w/g, function (char) { return char.toUpperCase(); });
2492
+ }
2493
+ return base
2494
+ .replace(/[_-]+/g, ' ')
2495
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
2496
+ .replace(/\s+/g, ' ')
2497
+ .trim()
2498
+ .replace(/\b\w/g, function (char) { return char.toUpperCase(); });
2031
2499
  }
2032
2500
  function truncateDisplayText(value, maxLength) {
2033
2501
  if (maxLength === void 0) { maxLength = AI_ASSISTANT_DISPLAY_STRING_LIMIT; }
@@ -2090,14 +2558,17 @@ function serializeMongoValue(value, maxLength) {
2090
2558
  }
2091
2559
  return truncateDisplayText(String(value), maxLength);
2092
2560
  }
2093
- function flattenForTable(doc) {
2561
+ function flattenForTable(doc, options) {
2094
2562
  var result = {};
2095
2563
  if (!doc || typeof doc !== 'object') {
2096
2564
  return result;
2097
2565
  }
2098
2566
  if (Object.prototype.hasOwnProperty.call(doc, '_id')) {
2099
2567
  var idValue_1 = doc._id;
2100
- if (idValue_1 !== null && idValue_1 !== undefined) {
2568
+ if (options === null || options === void 0 ? void 0 : options.includeIds) {
2569
+ result._id = idValue_1;
2570
+ }
2571
+ if ((options === null || options === void 0 ? void 0 : options.includeGroupFromId) && idValue_1 !== null && idValue_1 !== undefined) {
2101
2572
  if (isPlainObject(idValue_1) && !isMongoObjectId(idValue_1) && !(idValue_1 instanceof Date)) {
2102
2573
  Object.keys(idValue_1).forEach(function (key) {
2103
2574
  if (!key || Object.prototype.hasOwnProperty.call(result, key)) {
@@ -2140,7 +2611,12 @@ function flattenForTable(doc) {
2140
2611
  return result;
2141
2612
  }
2142
2613
  function buildDisplayTable(docs, options) {
2143
- var rowsRaw = Array.isArray(docs) ? docs.map(function (doc) { return flattenForTable(doc); }) : [];
2614
+ var rowsRaw = Array.isArray(docs)
2615
+ ? docs.map(function (doc) { return flattenForTable(doc, {
2616
+ includeIds: (options === null || options === void 0 ? void 0 : options.includeIds) === true,
2617
+ includeGroupFromId: (options === null || options === void 0 ? void 0 : options.includeGroupFromId) === true
2618
+ }); })
2619
+ : [];
2144
2620
  var stats = new Map();
2145
2621
  rowsRaw.forEach(function (row) {
2146
2622
  Object.keys(row).forEach(function (key) {
@@ -2496,7 +2972,8 @@ function normalizeAggregateFieldList(values) {
2496
2972
  return result;
2497
2973
  }
2498
2974
  function isCompletionFieldName(value) {
2499
- return String(value || '').toLowerCase().includes('complete');
2975
+ var normalized = String(value || '').toLowerCase();
2976
+ return normalized.includes('complete') || normalized.includes('close');
2500
2977
  }
2501
2978
  function isDateLikeFieldName(value) {
2502
2979
  var normalized = String(value || '').toLowerCase();
@@ -2523,7 +3000,7 @@ function matchContainsField(value, field) {
2523
3000
  });
2524
3001
  }
2525
3002
  function resolveAggregateCompletionFallback(pipeline) {
2526
- var e_1, _a;
3003
+ var e_3, _a;
2527
3004
  if (!Array.isArray(pipeline)) {
2528
3005
  return null;
2529
3006
  }
@@ -2536,7 +3013,7 @@ function resolveAggregateCompletionFallback(pipeline) {
2536
3013
  }
2537
3014
  var addFields = stage.$addFields;
2538
3015
  try {
2539
- for (var _b = (e_1 = void 0, __values(Object.keys(addFields))), _c = _b.next(); !_c.done; _c = _b.next()) {
3016
+ for (var _b = (e_3 = void 0, __values(Object.keys(addFields))), _c = _b.next(); !_c.done; _c = _b.next()) {
2540
3017
  var key = _c.value;
2541
3018
  if (!isCompletionFieldName(key)) {
2542
3019
  continue;
@@ -2550,12 +3027,12 @@ function resolveAggregateCompletionFallback(pipeline) {
2550
3027
  }
2551
3028
  }
2552
3029
  }
2553
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
3030
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
2554
3031
  finally {
2555
3032
  try {
2556
3033
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2557
3034
  }
2558
- finally { if (e_1) throw e_1.error; }
3035
+ finally { if (e_3) throw e_3.error; }
2559
3036
  }
2560
3037
  if (candidateField) {
2561
3038
  break;
@@ -2601,18 +3078,18 @@ function resolveAggregateCompletionFallback(pipeline) {
2601
3078
  statusFilter: statusFilter
2602
3079
  };
2603
3080
  }
3081
+ function buildIfNullChain(fields) {
3082
+ if (!fields.length) {
3083
+ return null;
3084
+ }
3085
+ var expr = "$".concat(fields[fields.length - 1]);
3086
+ for (var i = fields.length - 2; i >= 0; i -= 1) {
3087
+ expr = { $ifNull: ["$".concat(fields[i]), expr] };
3088
+ }
3089
+ return expr;
3090
+ }
2604
3091
  function buildAggregateCompletionFallbackPipeline(pipeline, fallback) {
2605
3092
  var _a;
2606
- var buildIfNullChain = function (fields) {
2607
- if (!fields.length) {
2608
- return null;
2609
- }
2610
- var expr = "$".concat(fields[fields.length - 1]);
2611
- for (var i = fields.length - 2; i >= 0; i -= 1) {
2612
- expr = { $ifNull: ["$".concat(fields[i]), expr] };
2613
- }
2614
- return expr;
2615
- };
2616
3093
  var matchStage = (_a = pipeline[fallback.matchIndex]) === null || _a === void 0 ? void 0 : _a.$match;
2617
3094
  if (!matchStage || typeof matchStage !== 'object') {
2618
3095
  return pipeline;
@@ -2645,6 +3122,163 @@ function buildAggregateCompletionFallbackPipeline(pipeline, fallback) {
2645
3122
  return stage;
2646
3123
  });
2647
3124
  }
3125
+ function normalizeCompletionStatusValue(value) {
3126
+ var normalized = String(value || '').toLowerCase();
3127
+ if (!normalized) {
3128
+ return null;
3129
+ }
3130
+ if (normalized.includes('complete')) {
3131
+ return 'complete';
3132
+ }
3133
+ if (normalized.includes('close')) {
3134
+ return 'close';
3135
+ }
3136
+ return null;
3137
+ }
3138
+ function applyCompletionStatusRegexFallback(match) {
3139
+ if (Array.isArray(match)) {
3140
+ return match.map(function (entry) { return applyCompletionStatusRegexFallback(entry); });
3141
+ }
3142
+ if (!match || typeof match !== 'object') {
3143
+ return match;
3144
+ }
3145
+ var result = {};
3146
+ Object.keys(match).forEach(function (key) {
3147
+ var value = match[key];
3148
+ if (key === 'status' || key === 'state') {
3149
+ if (typeof value === 'string') {
3150
+ var token = normalizeCompletionStatusValue(value);
3151
+ if (token) {
3152
+ result[key] = { $regex: token, $options: 'i' };
3153
+ return;
3154
+ }
3155
+ }
3156
+ result[key] = value;
3157
+ return;
3158
+ }
3159
+ if (key.startsWith('$')) {
3160
+ result[key] = applyCompletionStatusRegexFallback(value);
3161
+ return;
3162
+ }
3163
+ if (value && typeof value === 'object') {
3164
+ result[key] = applyCompletionStatusRegexFallback(value);
3165
+ return;
3166
+ }
3167
+ result[key] = value;
3168
+ });
3169
+ return result;
3170
+ }
3171
+ function buildCompletionFallbackSources(field) {
3172
+ return normalizeAggregateFieldList([
3173
+ field,
3174
+ 'date_completed',
3175
+ 'date_closed',
3176
+ 'completedAt',
3177
+ 'closedAt',
3178
+ 'completed_at',
3179
+ 'closed_at',
3180
+ 'date_completed_at',
3181
+ 'date_closed_at',
3182
+ 'completion_date',
3183
+ 'completed_date',
3184
+ 'date_finished',
3185
+ 'finished_at',
3186
+ 'createdAt',
3187
+ 'date_created'
3188
+ ]);
3189
+ }
3190
+ function resolveAggregateCompletionExprFallback(pipeline) {
3191
+ var e_4, _a;
3192
+ if (!Array.isArray(pipeline)) {
3193
+ return null;
3194
+ }
3195
+ for (var i = 0; i < pipeline.length; i += 1) {
3196
+ var stage = pipeline[i];
3197
+ if (!stage || typeof stage !== 'object' || !stage.$match || typeof stage.$match !== 'object') {
3198
+ continue;
3199
+ }
3200
+ var matchStage = stage.$match;
3201
+ var candidateField = '';
3202
+ if (matchStage.$expr) {
3203
+ var exprFields = extractExpressionFieldPaths(matchStage.$expr)
3204
+ .filter(function (field) { return isCompletionFieldName(field); });
3205
+ if (exprFields.length) {
3206
+ candidateField = exprFields[0];
3207
+ }
3208
+ }
3209
+ if (!candidateField) {
3210
+ try {
3211
+ for (var _b = (e_4 = void 0, __values(Object.keys(matchStage))), _c = _b.next(); !_c.done; _c = _b.next()) {
3212
+ var key = _c.value;
3213
+ if (key.startsWith('$')) {
3214
+ continue;
3215
+ }
3216
+ if (!isCompletionFieldName(key)) {
3217
+ continue;
3218
+ }
3219
+ var entry = matchStage[key];
3220
+ if (hasDateRangeOperators(entry) || entry instanceof Date) {
3221
+ candidateField = key;
3222
+ break;
3223
+ }
3224
+ }
3225
+ }
3226
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
3227
+ finally {
3228
+ try {
3229
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3230
+ }
3231
+ finally { if (e_4) throw e_4.error; }
3232
+ }
3233
+ }
3234
+ if (!candidateField) {
3235
+ continue;
3236
+ }
3237
+ var sources = buildCompletionFallbackSources(candidateField);
3238
+ if (!sources.length) {
3239
+ return null;
3240
+ }
3241
+ var hasStatus = matchContainsField(matchStage, 'status') || matchContainsField(matchStage, 'state');
3242
+ var statusFilter = !hasStatus
3243
+ ? { $or: [{ status: { $regex: 'complete', $options: 'i' } }, { state: { $regex: 'complete', $options: 'i' } }] }
3244
+ : null;
3245
+ return {
3246
+ matchIndex: i,
3247
+ field: candidateField,
3248
+ sources: sources,
3249
+ statusFilter: statusFilter
3250
+ };
3251
+ }
3252
+ return null;
3253
+ }
3254
+ function buildAggregateCompletionExprFallbackPipeline(pipeline, fallback) {
3255
+ var _a;
3256
+ var _b;
3257
+ var targetField = 'completed_at_effective';
3258
+ var replacedPipeline = replaceAggregateDateField(pipeline, fallback.field, targetField);
3259
+ var matchStage = (_b = replacedPipeline[fallback.matchIndex]) === null || _b === void 0 ? void 0 : _b.$match;
3260
+ if (!matchStage || typeof matchStage !== 'object') {
3261
+ return replacedPipeline;
3262
+ }
3263
+ var baseMatch = applyCompletionStatusRegexFallback(matchStage);
3264
+ var nextMatch = fallback.statusFilter ? { $and: [baseMatch, fallback.statusFilter] } : baseMatch;
3265
+ var addFieldsStage = { $addFields: (_a = {}, _a[targetField] = buildIfNullChain(fallback.sources), _a) };
3266
+ var alreadyHasField = replacedPipeline
3267
+ .slice(0, fallback.matchIndex)
3268
+ .some(function (stage) { return stage && typeof stage === 'object' && stage.$addFields && Object.prototype.hasOwnProperty.call(stage.$addFields, targetField); });
3269
+ var output = [];
3270
+ replacedPipeline.forEach(function (stage, index) {
3271
+ if (index === fallback.matchIndex) {
3272
+ if (!alreadyHasField) {
3273
+ output.push(addFieldsStage);
3274
+ }
3275
+ output.push({ $match: nextMatch });
3276
+ return;
3277
+ }
3278
+ output.push(stage);
3279
+ });
3280
+ return output;
3281
+ }
2648
3282
  function resolveAggregateUnwindFallback(pipeline) {
2649
3283
  var groupIndex = findAggregateGroupIndex(pipeline);
2650
3284
  if (groupIndex === -1) {
@@ -2751,14 +3385,261 @@ function buildAggregateUnwindFallbackPipeline(pipeline, fallback) {
2751
3385
  };
2752
3386
  return __spreadArray(__spreadArray(__spreadArray([], __read(before), false), [unwindStage], false), __read(after), false);
2753
3387
  }
2754
- function findAggregateDateField(pipeline) {
2755
- var fields = new Set();
2756
- (pipeline || []).forEach(function (stage) {
2757
- if (!stage || typeof stage !== 'object') {
2758
- return;
2759
- }
2760
- if (stage.$match && typeof stage.$match === 'object') {
2761
- collectDateFieldsFromMatch(stage.$match, fields);
3388
+ function isRegexMatchCondition(value) {
3389
+ if (!value) {
3390
+ return false;
3391
+ }
3392
+ if (value instanceof RegExp) {
3393
+ return true;
3394
+ }
3395
+ if (typeof value === 'object' && !Array.isArray(value)) {
3396
+ return Object.prototype.hasOwnProperty.call(value, '$regex');
3397
+ }
3398
+ return false;
3399
+ }
3400
+ function findRegexMatchInMatchObject(match, prefix) {
3401
+ var e_5, _a, e_6, _b;
3402
+ if (prefix === void 0) { prefix = ''; }
3403
+ if (Array.isArray(match)) {
3404
+ try {
3405
+ for (var match_1 = __values(match), match_1_1 = match_1.next(); !match_1_1.done; match_1_1 = match_1.next()) {
3406
+ var entry = match_1_1.value;
3407
+ var found = findRegexMatchInMatchObject(entry, prefix);
3408
+ if (found) {
3409
+ return found;
3410
+ }
3411
+ }
3412
+ }
3413
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
3414
+ finally {
3415
+ try {
3416
+ if (match_1_1 && !match_1_1.done && (_a = match_1.return)) _a.call(match_1);
3417
+ }
3418
+ finally { if (e_5) throw e_5.error; }
3419
+ }
3420
+ return null;
3421
+ }
3422
+ if (!match || typeof match !== 'object') {
3423
+ return null;
3424
+ }
3425
+ var keys = Object.keys(match);
3426
+ try {
3427
+ for (var keys_1 = __values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) {
3428
+ var key = keys_1_1.value;
3429
+ var value = match[key];
3430
+ if (key.startsWith('$')) {
3431
+ var found = findRegexMatchInMatchObject(value, prefix);
3432
+ if (found) {
3433
+ return found;
3434
+ }
3435
+ continue;
3436
+ }
3437
+ var currentPath = prefix ? "".concat(prefix, ".").concat(key) : key;
3438
+ if (isRegexMatchCondition(value)) {
3439
+ return { field: currentPath, condition: value };
3440
+ }
3441
+ if (value && typeof value === 'object') {
3442
+ var found = findRegexMatchInMatchObject(value, currentPath);
3443
+ if (found) {
3444
+ return found;
3445
+ }
3446
+ }
3447
+ }
3448
+ }
3449
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
3450
+ finally {
3451
+ try {
3452
+ if (keys_1_1 && !keys_1_1.done && (_b = keys_1.return)) _b.call(keys_1);
3453
+ }
3454
+ finally { if (e_6) throw e_6.error; }
3455
+ }
3456
+ return null;
3457
+ }
3458
+ function expandNameFieldCandidates(field) {
3459
+ var normalized = normalizeOptionalString(field);
3460
+ if (!normalized) {
3461
+ return [];
3462
+ }
3463
+ var parts = normalized.split('.').filter(Boolean);
3464
+ var leaf = parts[parts.length - 1] || normalized;
3465
+ var prefix = parts.length > 1 ? parts.slice(0, -1).join('.') : '';
3466
+ var withPrefix = function (value) { return (prefix ? "".concat(prefix, ".").concat(value) : value); };
3467
+ var candidates = [];
3468
+ var seen = new Set();
3469
+ var push = function (value) {
3470
+ if (!value) {
3471
+ return;
3472
+ }
3473
+ if (seen.has(value)) {
3474
+ return;
3475
+ }
3476
+ seen.add(value);
3477
+ candidates.push(value);
3478
+ };
3479
+ push(normalized);
3480
+ var leafLower = leaf.toLowerCase();
3481
+ var genericVariants = ['name', 'title', 'label', 'display_name', 'displayName', 'description'];
3482
+ genericVariants.forEach(function (variant) { return push(withPrefix(variant)); });
3483
+ if (!leafLower.endsWith('name')) {
3484
+ push(withPrefix("".concat(leaf, "_name")));
3485
+ push(withPrefix("".concat(leaf, "Name")));
3486
+ }
3487
+ if (leafLower.includes('chemical')) {
3488
+ [
3489
+ 'chemical',
3490
+ 'chemical_name',
3491
+ 'chemicalName',
3492
+ 'chem_name',
3493
+ 'chemName',
3494
+ 'product',
3495
+ 'product_name',
3496
+ 'productName',
3497
+ 'material',
3498
+ 'blend_name'
3499
+ ].forEach(function (variant) { return push(withPrefix(variant)); });
3500
+ push(withPrefix("".concat(leaf, ".name")));
3501
+ push(withPrefix("".concat(leaf, ".label")));
3502
+ push(withPrefix("".concat(leaf, ".product")));
3503
+ }
3504
+ if (leafLower.includes('customer')) {
3505
+ [
3506
+ 'customer',
3507
+ 'customer_name',
3508
+ 'customerName',
3509
+ 'company',
3510
+ 'company_name',
3511
+ 'companyName',
3512
+ 'account',
3513
+ 'account_name',
3514
+ 'accountName',
3515
+ 'name'
3516
+ ].forEach(function (variant) { return push(withPrefix(variant)); });
3517
+ push(withPrefix("".concat(leaf, ".name")));
3518
+ }
3519
+ if (leafLower.includes('well')) {
3520
+ [
3521
+ 'well',
3522
+ 'well_name',
3523
+ 'wellName',
3524
+ 'name',
3525
+ 'site',
3526
+ 'site_name',
3527
+ 'siteName',
3528
+ 'pad',
3529
+ 'pad_name',
3530
+ 'padName',
3531
+ 'api',
3532
+ 'api_number',
3533
+ 'apiNumber',
3534
+ 'well_number',
3535
+ 'wellNumber'
3536
+ ].forEach(function (variant) { return push(withPrefix(variant)); });
3537
+ push(withPrefix("".concat(leaf, ".name")));
3538
+ }
3539
+ return candidates.slice(0, AI_ASSISTANT_NAME_MATCH_FALLBACK_MAX_FIELDS);
3540
+ }
3541
+ function resolveAggregateNameMatchFallback(pipeline) {
3542
+ if (!Array.isArray(pipeline)) {
3543
+ return null;
3544
+ }
3545
+ for (var i = 0; i < pipeline.length; i += 1) {
3546
+ var stage = pipeline[i];
3547
+ if (!stage || typeof stage !== 'object' || !stage.$match || typeof stage.$match !== 'object') {
3548
+ continue;
3549
+ }
3550
+ var found = findRegexMatchInMatchObject(stage.$match);
3551
+ if (!found || !shouldApplyAssistantNameRegex(found.field)) {
3552
+ continue;
3553
+ }
3554
+ var fields = expandNameFieldCandidates(found.field);
3555
+ if (fields.length <= 1) {
3556
+ continue;
3557
+ }
3558
+ return {
3559
+ matchIndex: i,
3560
+ field: found.field,
3561
+ condition: found.condition,
3562
+ fields: fields
3563
+ };
3564
+ }
3565
+ return null;
3566
+ }
3567
+ function isEmptyMatchValue(value) {
3568
+ if (value === null || value === undefined) {
3569
+ return true;
3570
+ }
3571
+ if (Array.isArray(value)) {
3572
+ return value.length === 0;
3573
+ }
3574
+ if (typeof value === 'object') {
3575
+ return Object.keys(value).length === 0;
3576
+ }
3577
+ return false;
3578
+ }
3579
+ function stripMatchField(match, field) {
3580
+ if (Array.isArray(match)) {
3581
+ var strippedArray = match
3582
+ .map(function (entry) { return stripMatchField(entry, field); })
3583
+ .filter(function (entry) { return !isEmptyMatchValue(entry); });
3584
+ return strippedArray;
3585
+ }
3586
+ if (!match || typeof match !== 'object') {
3587
+ return match;
3588
+ }
3589
+ var result = {};
3590
+ Object.keys(match).forEach(function (key) {
3591
+ if (key === field) {
3592
+ return;
3593
+ }
3594
+ var value = match[key];
3595
+ if (key.startsWith('$')) {
3596
+ var stripped = stripMatchField(value, field);
3597
+ if (isEmptyMatchValue(stripped) && (key === '$and' || key === '$or')) {
3598
+ return;
3599
+ }
3600
+ result[key] = stripped;
3601
+ return;
3602
+ }
3603
+ if (value && typeof value === 'object') {
3604
+ var stripped = stripMatchField(value, field);
3605
+ if (!isEmptyMatchValue(stripped)) {
3606
+ result[key] = stripped;
3607
+ }
3608
+ return;
3609
+ }
3610
+ result[key] = value;
3611
+ });
3612
+ return result;
3613
+ }
3614
+ function buildAggregateNameMatchFallbackPipeline(pipeline, fallback) {
3615
+ var _a;
3616
+ var matchStage = (_a = pipeline[fallback.matchIndex]) === null || _a === void 0 ? void 0 : _a.$match;
3617
+ if (!matchStage || typeof matchStage !== 'object') {
3618
+ return pipeline;
3619
+ }
3620
+ var baseMatch = stripMatchField(matchStage, fallback.field);
3621
+ var orConditions = fallback.fields.map(function (field) {
3622
+ var _a;
3623
+ return (_a = {}, _a[field] = fallback.condition, _a);
3624
+ });
3625
+ var nextMatch = isEmptyMatchValue(baseMatch)
3626
+ ? { $or: orConditions }
3627
+ : { $and: [baseMatch, { $or: orConditions }] };
3628
+ return pipeline.map(function (stage, index) {
3629
+ if (index === fallback.matchIndex) {
3630
+ return { $match: nextMatch };
3631
+ }
3632
+ return stage;
3633
+ });
3634
+ }
3635
+ function findAggregateDateField(pipeline) {
3636
+ var fields = new Set();
3637
+ (pipeline || []).forEach(function (stage) {
3638
+ if (!stage || typeof stage !== 'object') {
3639
+ return;
3640
+ }
3641
+ if (stage.$match && typeof stage.$match === 'object') {
3642
+ collectDateFieldsFromMatch(stage.$match, fields);
2762
3643
  }
2763
3644
  });
2764
3645
  if (fields.size !== 1) {
@@ -2922,6 +3803,27 @@ function tokenizeCollectionText(value) {
2922
3803
  });
2923
3804
  return Array.from(new Set(tokens));
2924
3805
  }
3806
+ function expandAssistantTermSynonyms(text) {
3807
+ var base = normalizeOptionalString(text);
3808
+ if (!base) {
3809
+ return { expanded: '', matches: [] };
3810
+ }
3811
+ var expanded = base;
3812
+ var matches = [];
3813
+ AI_ASSISTANT_TERM_SYNONYMS.forEach(function (entry) {
3814
+ if (!entry.pattern.test(base)) {
3815
+ return;
3816
+ }
3817
+ var existing = expanded.toLowerCase();
3818
+ entry.expansions.forEach(function (expansion) {
3819
+ if (expansion && !existing.includes(expansion.toLowerCase())) {
3820
+ expanded = "".concat(expanded, " ").concat(expansion);
3821
+ }
3822
+ });
3823
+ matches.push({ term: entry.label, expansions: entry.expansions });
3824
+ });
3825
+ return { expanded: expanded, matches: matches };
3826
+ }
2925
3827
  function listAssistantCollections(db, dbName) {
2926
3828
  return __awaiter(this, void 0, void 0, function () {
2927
3829
  var cacheKey, cached, now, collections, names, _a;
@@ -2977,6 +3879,75 @@ function scoreCollectionMatch(requestedTokens, candidateName) {
2977
3879
  }
2978
3880
  return score;
2979
3881
  }
3882
+ function scoreCollectionMatchDetailed(requestedTokens, candidateName) {
3883
+ var candidateTokens = tokenizeCollectionText(candidateName);
3884
+ var tokenMatches = requestedTokens.filter(function (token) { return candidateTokens.includes(token); });
3885
+ var score = tokenMatches.length * 10;
3886
+ var requestedKey = normalizeCollectionKey(requestedTokens.join('-'));
3887
+ var candidateKey = normalizeCollectionKey(candidateName);
3888
+ var keyMatch = null;
3889
+ if (candidateKey === requestedKey && requestedKey) {
3890
+ score += 50;
3891
+ keyMatch = 'exact';
3892
+ }
3893
+ else if (requestedKey && (candidateKey.includes(requestedKey) || requestedKey.includes(candidateKey))) {
3894
+ score += 20;
3895
+ keyMatch = 'partial';
3896
+ }
3897
+ return {
3898
+ score: score,
3899
+ tokenMatches: tokenMatches,
3900
+ keyMatch: keyMatch,
3901
+ candidateTokens: candidateTokens
3902
+ };
3903
+ }
3904
+ function resolveCollectionHintsFromTokens(tokens, collectionNames, max) {
3905
+ if (max === void 0) { max = 5; }
3906
+ if (!tokens.length || !collectionNames.length) {
3907
+ return [];
3908
+ }
3909
+ return collectionNames
3910
+ .map(function (name) { return ({ name: name, score: scoreCollectionMatch(tokens, name) }); })
3911
+ .filter(function (entry) { return entry.score > 0; })
3912
+ .sort(function (a, b) { return b.score - a.score; })
3913
+ .slice(0, Math.max(max, 0))
3914
+ .map(function (entry) { return entry.name; });
3915
+ }
3916
+ function buildCollectionRankingDebugFromTokens(tokens, collectionNames, max) {
3917
+ if (max === void 0) { max = 8; }
3918
+ var requestedKey = normalizeCollectionKey(tokens.join('-'));
3919
+ if (!tokens.length || !collectionNames.length) {
3920
+ return {
3921
+ tokens: tokens,
3922
+ requestedKey: requestedKey,
3923
+ ranked: []
3924
+ };
3925
+ }
3926
+ var ranked = collectionNames
3927
+ .map(function (name) { return (__assign({ name: name }, scoreCollectionMatchDetailed(tokens, name))); })
3928
+ .filter(function (entry) { return entry.score > 0; })
3929
+ .sort(function (a, b) { return b.score - a.score; })
3930
+ .slice(0, Math.max(max, 0));
3931
+ return {
3932
+ tokens: tokens,
3933
+ requestedKey: requestedKey,
3934
+ ranked: ranked
3935
+ };
3936
+ }
3937
+ function buildCollectionSelectionDetail(tokens, collection) {
3938
+ var trimmed = normalizeOptionalString(collection);
3939
+ if (!trimmed) {
3940
+ return null;
3941
+ }
3942
+ var detail = scoreCollectionMatchDetailed(tokens, trimmed);
3943
+ return {
3944
+ collection: trimmed,
3945
+ score: detail.score,
3946
+ tokenMatches: detail.tokenMatches,
3947
+ keyMatch: detail.keyMatch,
3948
+ candidateTokens: detail.candidateTokens
3949
+ };
3950
+ }
2980
3951
  function findBestCollectionMatch(requested, collectionNames) {
2981
3952
  var requestedTokens = tokenizeCollectionText(requested);
2982
3953
  if (!requestedTokens.length || !collectionNames.length) {
@@ -3022,38 +3993,8 @@ function resolveAssistantCollectionName(db, dbName, requested) {
3022
3993
  });
3023
3994
  });
3024
3995
  }
3025
- function resolveAssistantCollectionHints(message, dbName, db) {
3026
- return __awaiter(this, void 0, void 0, function () {
3027
- var text, collectionNames, tokens;
3028
- return __generator(this, function (_a) {
3029
- switch (_a.label) {
3030
- case 0:
3031
- text = normalizeOptionalString(message);
3032
- if (!text) {
3033
- return [2 /*return*/, []];
3034
- }
3035
- return [4 /*yield*/, listAssistantCollections(db, dbName)];
3036
- case 1:
3037
- collectionNames = _a.sent();
3038
- if (!collectionNames.length) {
3039
- return [2 /*return*/, []];
3040
- }
3041
- tokens = tokenizeCollectionText(text);
3042
- if (!tokens.length) {
3043
- return [2 /*return*/, []];
3044
- }
3045
- return [2 /*return*/, collectionNames
3046
- .map(function (name) { return ({ name: name, score: scoreCollectionMatch(tokens, name) }); })
3047
- .filter(function (entry) { return entry.score > 0; })
3048
- .sort(function (a, b) { return b.score - a.score; })
3049
- .slice(0, 5)
3050
- .map(function (entry) { return entry.name; })];
3051
- }
3052
- });
3053
- });
3054
- }
3055
3996
  function findQueryDateField(query) {
3056
- var e_2, _a, e_3, _b;
3997
+ var e_7, _a, e_8, _b;
3057
3998
  if (!query || typeof query !== 'object') {
3058
3999
  return null;
3059
4000
  }
@@ -3067,12 +4008,12 @@ function findQueryDateField(query) {
3067
4008
  }
3068
4009
  }
3069
4010
  }
3070
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
4011
+ catch (e_7_1) { e_7 = { error: e_7_1 }; }
3071
4012
  finally {
3072
4013
  try {
3073
4014
  if (query_1_1 && !query_1_1.done && (_a = query_1.return)) _a.call(query_1);
3074
4015
  }
3075
- finally { if (e_2) throw e_2.error; }
4016
+ finally { if (e_7) throw e_7.error; }
3076
4017
  }
3077
4018
  return null;
3078
4019
  }
@@ -3091,12 +4032,12 @@ function findQueryDateField(query) {
3091
4032
  }
3092
4033
  }
3093
4034
  }
3094
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
4035
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
3095
4036
  finally {
3096
4037
  try {
3097
4038
  if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
3098
4039
  }
3099
- finally { if (e_3) throw e_3.error; }
4040
+ finally { if (e_8) throw e_8.error; }
3100
4041
  }
3101
4042
  return null;
3102
4043
  }
@@ -3114,6 +4055,117 @@ function replaceQueryField(query, fromField, toField) {
3114
4055
  });
3115
4056
  return result;
3116
4057
  }
4058
+ function extractDateRangeConditions(query) {
4059
+ if (!query || typeof query !== 'object' || query instanceof Date) {
4060
+ return [];
4061
+ }
4062
+ var results = [];
4063
+ Object.keys(query).forEach(function (key) {
4064
+ if (key.startsWith('$')) {
4065
+ return;
4066
+ }
4067
+ var value = query[key];
4068
+ if (value instanceof Date) {
4069
+ results.push({ field: key, condition: value });
4070
+ return;
4071
+ }
4072
+ if (value && typeof value === 'object' && hasDateRangeOperators(value)) {
4073
+ results.push({ field: key, condition: value });
4074
+ }
4075
+ });
4076
+ return results;
4077
+ }
4078
+ function expandQueryDateFallbacks(query) {
4079
+ if (!query || typeof query !== 'object') {
4080
+ return null;
4081
+ }
4082
+ var addedFields = [];
4083
+ var pushField = function (field) {
4084
+ if (!field) {
4085
+ return;
4086
+ }
4087
+ if (addedFields.includes(field)) {
4088
+ return;
4089
+ }
4090
+ addedFields.push(field);
4091
+ };
4092
+ var expandOrArray = function (orArray) {
4093
+ var existingFields = new Set();
4094
+ orArray.forEach(function (entry) {
4095
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
4096
+ return;
4097
+ }
4098
+ Object.keys(entry).forEach(function (key) {
4099
+ if (!key.startsWith('$')) {
4100
+ existingFields.add(key);
4101
+ }
4102
+ });
4103
+ });
4104
+ var extended = __spreadArray([], __read(orArray), false);
4105
+ orArray.forEach(function (entry) {
4106
+ if (!entry || typeof entry !== 'object' || Array.isArray(entry)) {
4107
+ return;
4108
+ }
4109
+ var dateConditions = extractDateRangeConditions(entry);
4110
+ dateConditions.forEach(function (condition) {
4111
+ var fallback = AI_ASSISTANT_DATE_FALLBACKS[condition.field];
4112
+ if (fallback && !existingFields.has(fallback)) {
4113
+ extended = __spreadArray(__spreadArray([], __read(extended), false), [replaceQueryField(entry, condition.field, fallback)], false);
4114
+ existingFields.add(fallback);
4115
+ pushField(fallback);
4116
+ }
4117
+ });
4118
+ if (!existingFields.has('date_original')) {
4119
+ var candidate = dateConditions.find(function (condition) { return condition.field.startsWith('date_') && condition.field !== 'date_original'; });
4120
+ if (candidate) {
4121
+ extended = __spreadArray(__spreadArray([], __read(extended), false), [replaceQueryField(entry, candidate.field, 'date_original')], false);
4122
+ existingFields.add('date_original');
4123
+ pushField('date_original');
4124
+ }
4125
+ }
4126
+ });
4127
+ return extended;
4128
+ };
4129
+ var visit = function (value) {
4130
+ if (Array.isArray(value)) {
4131
+ var changed_1 = false;
4132
+ var nextArray = value.map(function (entry) {
4133
+ var visited = visit(entry);
4134
+ if (visited.changed) {
4135
+ changed_1 = true;
4136
+ }
4137
+ return visited.value;
4138
+ });
4139
+ return { value: changed_1 ? nextArray : value, changed: changed_1 };
4140
+ }
4141
+ if (!value || typeof value !== 'object') {
4142
+ return { value: value, changed: false };
4143
+ }
4144
+ var changed = false;
4145
+ var next = __assign({}, value);
4146
+ Object.keys(value).forEach(function (key) {
4147
+ if (key === '$or' && Array.isArray(value.$or)) {
4148
+ var expanded = expandOrArray(value.$or);
4149
+ if (expanded.length !== value.$or.length) {
4150
+ next.$or = expanded;
4151
+ changed = true;
4152
+ }
4153
+ return;
4154
+ }
4155
+ var visited = visit(value[key]);
4156
+ if (visited.changed) {
4157
+ next[key] = visited.value;
4158
+ changed = true;
4159
+ }
4160
+ });
4161
+ return { value: changed ? next : value, changed: changed };
4162
+ };
4163
+ var result = visit(query);
4164
+ if (!result.changed || !addedFields.length) {
4165
+ return null;
4166
+ }
4167
+ return { query: result.value, fields: addedFields };
4168
+ }
3117
4169
  function resolveQueryDateFieldFallback(query) {
3118
4170
  var dateField = findQueryDateField(query);
3119
4171
  if (!dateField) {
@@ -3126,7 +4178,7 @@ function resolveQueryDateFieldFallback(query) {
3126
4178
  return { from: dateField, to: fallback };
3127
4179
  }
3128
4180
  function containsForbiddenMongoOperators(value) {
3129
- var e_4, _a;
4181
+ var e_9, _a;
3130
4182
  if (!value || typeof value !== 'object') {
3131
4183
  return false;
3132
4184
  }
@@ -3145,12 +4197,12 @@ function containsForbiddenMongoOperators(value) {
3145
4197
  }
3146
4198
  }
3147
4199
  }
3148
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
4200
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
3149
4201
  finally {
3150
4202
  try {
3151
4203
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3152
4204
  }
3153
- finally { if (e_4) throw e_4.error; }
4205
+ finally { if (e_9) throw e_9.error; }
3154
4206
  }
3155
4207
  return false;
3156
4208
  }
@@ -3384,8 +4436,8 @@ function applyCodexStreamStatusHandler(runOptions, streamStatusHandler) {
3384
4436
  }
3385
4437
  function waitForCodexWorkerMessage(worker, streamStatusHandler) {
3386
4438
  return __awaiter(this, void 0, void 0, function () {
3387
- var _a, _b, _c, _d, message, payload, status_1, e_5_1;
3388
- var _e, e_5, _f, _g;
4439
+ var _a, _b, _c, _d, message, payload, status_1, e_10_1;
4440
+ var _e, e_10, _f, _g;
3389
4441
  return __generator(this, function (_h) {
3390
4442
  switch (_h.label) {
3391
4443
  case 0:
@@ -3412,8 +4464,8 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
3412
4464
  return [3 /*break*/, 1];
3413
4465
  case 4: return [3 /*break*/, 11];
3414
4466
  case 5:
3415
- e_5_1 = _h.sent();
3416
- e_5 = { error: e_5_1 };
4467
+ e_10_1 = _h.sent();
4468
+ e_10 = { error: e_10_1 };
3417
4469
  return [3 /*break*/, 11];
3418
4470
  case 6:
3419
4471
  _h.trys.push([6, , 9, 10]);
@@ -3424,7 +4476,7 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
3424
4476
  _h.label = 8;
3425
4477
  case 8: return [3 /*break*/, 10];
3426
4478
  case 9:
3427
- if (e_5) throw e_5.error;
4479
+ if (e_10) throw e_10.error;
3428
4480
  return [7 /*endfinally*/];
3429
4481
  case 10: return [7 /*endfinally*/];
3430
4482
  case 11: throw new CodexWorkerBootstrapError('Codex worker exited before completing.');
@@ -3776,6 +4828,12 @@ function buildAssistantContext(input, userContext) {
3776
4828
  if (collectionHints.length) {
3777
4829
  lines.push("Collection hints: ".concat(collectionHints.join(', ')));
3778
4830
  }
4831
+ var termHints = Array.isArray(userContext === null || userContext === void 0 ? void 0 : userContext.termHints)
4832
+ ? userContext === null || userContext === void 0 ? void 0 : userContext.termHints.filter(Boolean)
4833
+ : [];
4834
+ if (termHints.length) {
4835
+ lines.push("Term hints: ".concat(termHints.join('; ')));
4836
+ }
3779
4837
  var mongoDb = normalizeOptionalString((_c = input === null || input === void 0 ? void 0 : input.mongo) === null || _c === void 0 ? void 0 : _c.database);
3780
4838
  var mongoDbs = Array.isArray((_d = input === null || input === void 0 ? void 0 : input.mongo) === null || _d === void 0 ? void 0 : _d.databases)
3781
4839
  ? input.mongo.databases.map(function (value) { return normalizeOptionalString(value); }).filter(Boolean)
@@ -3806,7 +4864,7 @@ function normalizeRouteMatchKey(value) {
3806
4864
  return normalizeRouteKey(value).toLowerCase();
3807
4865
  }
3808
4866
  function buildClientRouteIndex() {
3809
- var e_6, _a;
4867
+ var e_11, _a;
3810
4868
  var _b;
3811
4869
  var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
3812
4870
  var set = new Set();
@@ -3825,12 +4883,12 @@ function buildClientRouteIndex() {
3825
4883
  }
3826
4884
  }
3827
4885
  }
3828
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
4886
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
3829
4887
  finally {
3830
4888
  try {
3831
4889
  if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
3832
4890
  }
3833
- finally { if (e_6) throw e_6.error; }
4891
+ finally { if (e_11) throw e_11.error; }
3834
4892
  }
3835
4893
  return { set: set, map: map, size: routes.length };
3836
4894
  }
@@ -3956,7 +5014,7 @@ function sanitizeAssistantResponse(value) {
3956
5014
  return normalizeAssistantRoutes(normalizedCurrency);
3957
5015
  }
3958
5016
  function evaluateAssistantGuardrails(message) {
3959
- var e_7, _a;
5017
+ var e_12, _a;
3960
5018
  var normalized = String(message || '').toLowerCase();
3961
5019
  var patterns = [
3962
5020
  {
@@ -4002,12 +5060,12 @@ function evaluateAssistantGuardrails(message) {
4002
5060
  }
4003
5061
  }
4004
5062
  }
4005
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
5063
+ catch (e_12_1) { e_12 = { error: e_12_1 }; }
4006
5064
  finally {
4007
5065
  try {
4008
5066
  if (patterns_1_1 && !patterns_1_1.done && (_a = patterns_1.return)) _a.call(patterns_1);
4009
5067
  }
4010
- finally { if (e_7) throw e_7.error; }
5068
+ finally { if (e_12) throw e_12.error; }
4011
5069
  }
4012
5070
  return null;
4013
5071
  }
@@ -4094,20 +5152,262 @@ function normalizeAiFormFields(fields) {
4094
5152
  })
4095
5153
  .filter(function (field) { return !!field; });
4096
5154
  }
5155
+ function tokenizeArithmeticExpression(expression) {
5156
+ var tokens = [];
5157
+ var i = 0;
5158
+ while (i < expression.length) {
5159
+ var char = expression[i];
5160
+ if (/\s/.test(char)) {
5161
+ i += 1;
5162
+ continue;
5163
+ }
5164
+ if (/[()+\-*/]/.test(char)) {
5165
+ tokens.push(char);
5166
+ i += 1;
5167
+ continue;
5168
+ }
5169
+ if (/\d|\./.test(char)) {
5170
+ var j = i + 1;
5171
+ while (j < expression.length && /[\d.]/.test(expression[j])) {
5172
+ j += 1;
5173
+ }
5174
+ tokens.push(expression.slice(i, j));
5175
+ i = j;
5176
+ continue;
5177
+ }
5178
+ return null;
5179
+ }
5180
+ return tokens;
5181
+ }
5182
+ function evaluateArithmeticExpression(expression) {
5183
+ var e_13, _a, e_14, _b;
5184
+ var tokens = tokenizeArithmeticExpression(expression);
5185
+ if (!tokens || !tokens.length) {
5186
+ return null;
5187
+ }
5188
+ var output = [];
5189
+ var ops = [];
5190
+ var precedence = { '+': 1, '-': 1, '*': 2, '/': 2 };
5191
+ var prevToken = '';
5192
+ var pushOperator = function (op) {
5193
+ while (ops.length) {
5194
+ var top_1 = ops[ops.length - 1];
5195
+ if (top_1 === '(') {
5196
+ break;
5197
+ }
5198
+ if ((precedence[top_1] || 0) >= (precedence[op] || 0)) {
5199
+ output.push(ops.pop());
5200
+ continue;
5201
+ }
5202
+ break;
5203
+ }
5204
+ ops.push(op);
5205
+ };
5206
+ try {
5207
+ for (var tokens_1 = __values(tokens), tokens_1_1 = tokens_1.next(); !tokens_1_1.done; tokens_1_1 = tokens_1.next()) {
5208
+ var token = tokens_1_1.value;
5209
+ if (token === '(') {
5210
+ ops.push(token);
5211
+ prevToken = token;
5212
+ continue;
5213
+ }
5214
+ if (token === ')') {
5215
+ while (ops.length && ops[ops.length - 1] !== '(') {
5216
+ output.push(ops.pop());
5217
+ }
5218
+ if (!ops.length) {
5219
+ return null;
5220
+ }
5221
+ ops.pop();
5222
+ prevToken = token;
5223
+ continue;
5224
+ }
5225
+ if (precedence[token]) {
5226
+ if (!prevToken || prevToken === '(' || precedence[prevToken]) {
5227
+ output.push('0');
5228
+ }
5229
+ pushOperator(token);
5230
+ prevToken = token;
5231
+ continue;
5232
+ }
5233
+ if (!/^\d+(\.\d+)?$/.test(token)) {
5234
+ return null;
5235
+ }
5236
+ output.push(token);
5237
+ prevToken = token;
5238
+ }
5239
+ }
5240
+ catch (e_13_1) { e_13 = { error: e_13_1 }; }
5241
+ finally {
5242
+ try {
5243
+ if (tokens_1_1 && !tokens_1_1.done && (_a = tokens_1.return)) _a.call(tokens_1);
5244
+ }
5245
+ finally { if (e_13) throw e_13.error; }
5246
+ }
5247
+ while (ops.length) {
5248
+ var op = ops.pop();
5249
+ if (op === '(' || op === ')') {
5250
+ return null;
5251
+ }
5252
+ output.push(op);
5253
+ }
5254
+ var stack = [];
5255
+ try {
5256
+ for (var output_1 = __values(output), output_1_1 = output_1.next(); !output_1_1.done; output_1_1 = output_1.next()) {
5257
+ var token = output_1_1.value;
5258
+ if (precedence[token]) {
5259
+ if (stack.length < 2) {
5260
+ return null;
5261
+ }
5262
+ var b = stack.pop();
5263
+ var a = stack.pop();
5264
+ switch (token) {
5265
+ case '+':
5266
+ stack.push(a + b);
5267
+ break;
5268
+ case '-':
5269
+ stack.push(a - b);
5270
+ break;
5271
+ case '*':
5272
+ stack.push(a * b);
5273
+ break;
5274
+ case '/':
5275
+ stack.push(a / b);
5276
+ break;
5277
+ default:
5278
+ return null;
5279
+ }
5280
+ continue;
5281
+ }
5282
+ stack.push(Number(token));
5283
+ }
5284
+ }
5285
+ catch (e_14_1) { e_14 = { error: e_14_1 }; }
5286
+ finally {
5287
+ try {
5288
+ if (output_1_1 && !output_1_1.done && (_b = output_1.return)) _b.call(output_1);
5289
+ }
5290
+ finally { if (e_14) throw e_14.error; }
5291
+ }
5292
+ if (stack.length !== 1 || Number.isNaN(stack[0])) {
5293
+ return null;
5294
+ }
5295
+ return stack[0];
5296
+ }
5297
+ function resolveDateExpression(expression) {
5298
+ var trimmed = String(expression || '').trim();
5299
+ if (!trimmed) {
5300
+ return null;
5301
+ }
5302
+ var quotedMatch = trimmed.match(/^['"](.+?)['"]$/);
5303
+ if (quotedMatch) {
5304
+ var date = new Date(quotedMatch[1]);
5305
+ return Number.isNaN(date.getTime()) ? null : date.toISOString();
5306
+ }
5307
+ if (trimmed === 'Date.now()') {
5308
+ return new Date(Date.now()).toISOString();
5309
+ }
5310
+ var nowMatch = trimmed.match(/^Date\.now\(\)\s*([+-])\s*(.+)$/);
5311
+ if (nowMatch) {
5312
+ var delta = evaluateArithmeticExpression(nowMatch[2]);
5313
+ if (delta === null) {
5314
+ return null;
5315
+ }
5316
+ var base = Date.now();
5317
+ var computed = nowMatch[1] === '-' ? base - delta : base + delta;
5318
+ return new Date(computed).toISOString();
5319
+ }
5320
+ var numeric = evaluateArithmeticExpression(trimmed);
5321
+ if (numeric !== null) {
5322
+ var date = new Date(numeric);
5323
+ return Number.isNaN(date.getTime()) ? null : date.toISOString();
5324
+ }
5325
+ return null;
5326
+ }
5327
+ function replaceNewDateExpressions(input) {
5328
+ var output = '';
5329
+ var index = 0;
5330
+ while (index < input.length) {
5331
+ var start = input.indexOf('new Date(', index);
5332
+ if (start === -1) {
5333
+ output += input.slice(index);
5334
+ break;
5335
+ }
5336
+ output += input.slice(index, start);
5337
+ var cursor = start + 'new Date('.length;
5338
+ var depth = 1;
5339
+ while (cursor < input.length && depth > 0) {
5340
+ var char = input[cursor];
5341
+ if (char === '(') {
5342
+ depth += 1;
5343
+ }
5344
+ else if (char === ')') {
5345
+ depth -= 1;
5346
+ }
5347
+ cursor += 1;
5348
+ }
5349
+ if (depth !== 0) {
5350
+ output += input.slice(start);
5351
+ break;
5352
+ }
5353
+ var inner = input.slice(start + 'new Date('.length, cursor - 1);
5354
+ var iso = resolveDateExpression(inner);
5355
+ if (iso) {
5356
+ output += "{\"$date\":\"".concat(iso, "\"}");
5357
+ }
5358
+ else {
5359
+ output += input.slice(start, cursor);
5360
+ }
5361
+ index = cursor;
5362
+ }
5363
+ return output;
5364
+ }
5365
+ function replaceIsoDateExpressions(input) {
5366
+ return input.replace(/ISODate\(([^)]+)\)/g, function (_match, inner) {
5367
+ var iso = resolveDateExpression(inner);
5368
+ return iso ? "{\"$date\":\"".concat(iso, "\"}") : _match;
5369
+ });
5370
+ }
5371
+ function preprocessJsonLike(content) {
5372
+ var normalized = content;
5373
+ normalized = replaceNewDateExpressions(normalized);
5374
+ normalized = replaceIsoDateExpressions(normalized);
5375
+ return normalized;
5376
+ }
5377
+ function convertExtendedDates(value) {
5378
+ if (Array.isArray(value)) {
5379
+ return value.map(function (entry) { return convertExtendedDates(entry); });
5380
+ }
5381
+ if (!value || typeof value !== 'object') {
5382
+ return value;
5383
+ }
5384
+ var keys = Object.keys(value);
5385
+ if (keys.length === 1 && keys[0] === '$date') {
5386
+ var raw = value.$date;
5387
+ var date = new Date(raw);
5388
+ return Number.isNaN(date.getTime()) ? value : date;
5389
+ }
5390
+ var output = {};
5391
+ keys.forEach(function (key) {
5392
+ output[key] = convertExtendedDates(value[key]);
5393
+ });
5394
+ return output;
5395
+ }
4097
5396
  function parseJsonObject(content) {
4098
5397
  if (!content || typeof content !== 'string') {
4099
5398
  return null;
4100
5399
  }
5400
+ var normalized = preprocessJsonLike(content);
4101
5401
  try {
4102
- return JSON.parse(content);
5402
+ return convertExtendedDates(JSON.parse(normalized));
4103
5403
  }
4104
5404
  catch (_a) {
4105
- var match = content.match(/\{[\s\S]*\}/);
5405
+ var match = normalized.match(/\{[\s\S]*\}/);
4106
5406
  if (!match) {
4107
5407
  return null;
4108
5408
  }
4109
5409
  try {
4110
- return JSON.parse(match[0]);
5410
+ return convertExtendedDates(JSON.parse(match[0]));
4111
5411
  }
4112
5412
  catch (_b) {
4113
5413
  return null;
@@ -4171,8 +5471,8 @@ function handleCodexUpload(id_conversation, file_name, content_base64, size, con
4171
5471
  }
4172
5472
  function readAttachmentContents(attachments) {
4173
5473
  return __awaiter(this, void 0, void 0, function () {
4174
- var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_8_1;
4175
- var e_8, _b;
5474
+ var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_15_1;
5475
+ var e_15, _b;
4176
5476
  return __generator(this, function (_c) {
4177
5477
  switch (_c.label) {
4178
5478
  case 0:
@@ -4251,14 +5551,14 @@ function readAttachmentContents(attachments) {
4251
5551
  return [3 /*break*/, 2];
4252
5552
  case 10: return [3 /*break*/, 13];
4253
5553
  case 11:
4254
- e_8_1 = _c.sent();
4255
- e_8 = { error: e_8_1 };
5554
+ e_15_1 = _c.sent();
5555
+ e_15 = { error: e_15_1 };
4256
5556
  return [3 /*break*/, 13];
4257
5557
  case 12:
4258
5558
  try {
4259
5559
  if (attachments_1_1 && !attachments_1_1.done && (_b = attachments_1.return)) _b.call(attachments_1);
4260
5560
  }
4261
- finally { if (e_8) throw e_8.error; }
5561
+ finally { if (e_15) throw e_15.error; }
4262
5562
  return [7 /*endfinally*/];
4263
5563
  case 13: return [2 /*return*/, {
4264
5564
  promptText: chunks.length ? "\n\nAttachments:\n".concat(chunks.join('\n\n')) : '',
@@ -4435,7 +5735,7 @@ function estimateUsage(messages, responseText, model) {
4435
5735
  };
4436
5736
  }
4437
5737
  function evaluateGuardrails(message) {
4438
- var e_9, _a;
5738
+ var e_16, _a;
4439
5739
  var normalized = String(message || '').toLowerCase();
4440
5740
  var patterns = [
4441
5741
  { 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.' },
@@ -4457,12 +5757,12 @@ function evaluateGuardrails(message) {
4457
5757
  }
4458
5758
  }
4459
5759
  }
4460
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
5760
+ catch (e_16_1) { e_16 = { error: e_16_1 }; }
4461
5761
  finally {
4462
5762
  try {
4463
5763
  if (patterns_2_1 && !patterns_2_1.done && (_a = patterns_2.return)) _a.call(patterns_2);
4464
5764
  }
4465
- finally { if (e_9) throw e_9.error; }
5765
+ finally { if (e_16) throw e_16.error; }
4466
5766
  }
4467
5767
  return null;
4468
5768
  }