@resolveio/server-lib 20.15.6 → 20.15.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -246,6 +246,13 @@ var AI_ASSISTANT_COLLECTION_STOPWORDS = new Set([
246
246
  'missing',
247
247
  'overdue'
248
248
  ]);
249
+ var AI_ASSISTANT_TERM_SYNONYMS = [
250
+ {
251
+ label: 'truck treating jobs',
252
+ pattern: /\btruck\s+treating\s+jobs?\b/i,
253
+ expansions: ['truck treating deliveries', 'truck-treating-deliveries', 'truck treating route events']
254
+ }
255
+ ];
249
256
  var AI_ASSISTANT_SYSTEM_PROMPT = [
250
257
  'You are the ResolveIO in-app AI assistant running with read-only access to the codebase.',
251
258
  'Core rules:',
@@ -259,6 +266,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
259
266
  '- 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
267
  '- 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
268
  '- Map user wording to internal collections/fields yourself. Do not ask for property names unless required to run a query.',
269
+ '- Use term hints from context (synonym expansions) when mapping user language to collections.',
262
270
  '- 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
271
  '- Prefer running a small Mongo read over asking multiple questions.',
264
272
  '- For any data request (counts, lists, breakdowns, recent/last items), you MUST run a MONGO_READ or MONGO_AGG before answering.',
@@ -275,6 +283,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
275
283
  '- When you reference database results, summarize first, then include a Markdown table.',
276
284
  '- When presenting record lists or aggregates, produce a Markdown table (pipes).',
277
285
  '- Never show raw JSON dumps.',
286
+ '- 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
287
  '- Do not include `_id` & `__v` & `id_<other collection _id property>` in tables by default.',
279
288
  '- 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
289
  '- Rename `createdAt` to `Created At` and `updatedAt` to `Updated At` in tables.',
@@ -1039,11 +1048,21 @@ function executeAiAssistantCodexRun(payload, context) {
1039
1048
  insertResult = _d.sent();
1040
1049
  assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
1041
1050
  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) {
1051
+ var runStart, steps, recordStep, progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, dataQuestion, lastDirective, toolResponseDebug, toolError, termHints, collectionHints, contextRoute, contextMode, hintSeed, termExpansion, hintText, dbName, db, _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, finishedAt, finalMetadata, finalAssistantDoc;
1052
+ var _f, _g, _h, _j, _k, _l, _m, _o;
1053
+ return __generator(this, function (_p) {
1054
+ switch (_p.label) {
1046
1055
  case 0:
1056
+ runStart = Date.now();
1057
+ steps = [];
1058
+ recordStep = function (step, details) {
1059
+ steps.push({
1060
+ step: step,
1061
+ at: new Date().toISOString(),
1062
+ ms: Date.now() - runStart,
1063
+ details: details
1064
+ });
1065
+ };
1047
1066
  progressTracker = createAssistantProgressTracker(assistantMessageId, initialProgress);
1048
1067
  streamProgress = createAssistantStreamProgressHandler(progressTracker);
1049
1068
  assistantContent = '';
@@ -1054,38 +1073,52 @@ function executeAiAssistantCodexRun(payload, context) {
1054
1073
  lastDirective = null;
1055
1074
  toolResponseDebug = null;
1056
1075
  toolError = null;
1057
- _g.label = 1;
1058
- case 1:
1059
- _g.trys.push([1, 30, 31, 32]);
1076
+ termHints = [];
1060
1077
  collectionHints = [];
1061
- _g.label = 2;
1078
+ contextRoute = normalizeOptionalString((_f = input === null || input === void 0 ? void 0 : input.context) === null || _f === void 0 ? void 0 : _f.route);
1079
+ contextMode = normalizeOptionalString((_g = input === null || input === void 0 ? void 0 : input.context) === null || _g === void 0 ? void 0 : _g.mode);
1080
+ recordStep('Queued', { requestId: requestId || undefined });
1081
+ _p.label = 1;
1082
+ case 1:
1083
+ _p.trys.push([1, 30, 31, 32]);
1084
+ hintSeed = [message, contextRoute].filter(Boolean).join(' ');
1085
+ termExpansion = expandAssistantTermSynonyms(hintSeed);
1086
+ hintText = termExpansion.expanded || hintSeed;
1087
+ termHints = termExpansion.matches.map(function (match) { return "".concat(match.term, " -> ").concat(match.expansions.join(', ')); });
1088
+ recordStep('Planning: term expansion', {
1089
+ termMatches: termExpansion.matches.length ? termExpansion.matches : undefined
1090
+ });
1091
+ _p.label = 2;
1062
1092
  case 2:
1063
- _g.trys.push([2, 4, , 5]);
1093
+ _p.trys.push([2, 4, , 5]);
1064
1094
  dbName = resolveAssistantDatabaseName(undefined, input.mongo);
1065
1095
  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
1096
  return [4 /*yield*/, resolveAssistantCollectionHints(hintText, dbName, db)];
1071
1097
  case 3:
1072
- collectionHints = _g.sent();
1098
+ collectionHints = _p.sent();
1073
1099
  return [3 /*break*/, 5];
1074
1100
  case 4:
1075
- _a = _g.sent();
1101
+ _a = _p.sent();
1076
1102
  collectionHints = [];
1077
1103
  return [3 /*break*/, 5];
1078
1104
  case 5:
1105
+ recordStep('Planning: collection hints', {
1106
+ contextRoute: contextRoute || undefined,
1107
+ contextMode: contextMode || undefined,
1108
+ collectionHints: collectionHints.length ? collectionHints : undefined,
1109
+ termHints: termHints.length ? termHints : undefined
1110
+ });
1079
1111
  assistantContext = buildAssistantContext(input, {
1080
1112
  isSuperAdmin: isSuperAdmin,
1081
1113
  hasInvoiceAccess: hasInvoiceAccess,
1082
1114
  customerId: customerId,
1083
- collectionHints: collectionHints
1115
+ collectionHints: collectionHints,
1116
+ termHints: termHints
1084
1117
  });
1085
1118
  prompt_1 = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1086
1119
  return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
1087
1120
  case 6:
1088
- workspaceRoot = _g.sent();
1121
+ workspaceRoot = _p.sent();
1089
1122
  codexConfig = resolveCodexSettings();
1090
1123
  runOptions = {
1091
1124
  timeoutMs: resolveCodexTimeoutMs(),
@@ -1104,52 +1137,73 @@ function executeAiAssistantCodexRun(payload, context) {
1104
1137
  directiveText = '';
1105
1138
  directive = null;
1106
1139
  if (!dataQuestion) return [3 /*break*/, 10];
1140
+ recordStep('Directive: determine tool', { type: 'data-question' });
1107
1141
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1108
- _g.label = 7;
1142
+ _p.label = 7;
1109
1143
  case 7:
1110
- _g.trys.push([7, 9, , 10]);
1144
+ _p.trys.push([7, 9, , 10]);
1111
1145
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1112
1146
  case 8:
1113
- directiveText = _g.sent();
1147
+ directiveText = _p.sent();
1114
1148
  forcedDirective = extractAssistantMongoDirective(directiveText);
1115
1149
  if (forcedDirective) {
1116
1150
  directive = forcedDirective;
1117
1151
  directiveSource = 'model';
1118
1152
  lastDirective = forcedDirective;
1153
+ recordStep('Directive resolved', {
1154
+ source: directiveSource,
1155
+ type: directive.type,
1156
+ collection: normalizeOptionalString((_h = directive.payload) === null || _h === void 0 ? void 0 : _h.collection) || undefined,
1157
+ permissionView: normalizeOptionalString((_j = directive.payload) === null || _j === void 0 ? void 0 : _j.permissionView) || undefined
1158
+ });
1119
1159
  }
1120
1160
  return [3 /*break*/, 10];
1121
1161
  case 9:
1122
- _b = _g.sent();
1162
+ _b = _p.sent();
1123
1163
  return [3 /*break*/, 10];
1124
1164
  case 10:
1125
1165
  if (!!directive) return [3 /*break*/, 12];
1166
+ recordStep('Response: draft initial answer', { mode: 'full' });
1126
1167
  return [4 /*yield*/, runCodexInWorkerThread(prompt_1, runOptions, codexConfig, streamProgress)];
1127
1168
  case 11:
1128
- responseText = _g.sent();
1169
+ responseText = _p.sent();
1129
1170
  directive = extractAssistantMongoDirective(responseText);
1130
1171
  if (directive) {
1131
1172
  directiveSource = 'model';
1132
1173
  lastDirective = directive;
1174
+ recordStep('Directive resolved', {
1175
+ source: directiveSource,
1176
+ type: directive.type,
1177
+ collection: normalizeOptionalString((_k = directive.payload) === null || _k === void 0 ? void 0 : _k.collection) || undefined,
1178
+ permissionView: normalizeOptionalString((_l = directive.payload) === null || _l === void 0 ? void 0 : _l.permissionView) || undefined
1179
+ });
1133
1180
  }
1134
- _g.label = 12;
1181
+ _p.label = 12;
1135
1182
  case 12:
1136
1183
  if (!(!directive && dataQuestion)) return [3 /*break*/, 16];
1184
+ recordStep('Directive: forced retry', { mode: 'directive-only' });
1137
1185
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1138
- _g.label = 13;
1186
+ _p.label = 13;
1139
1187
  case 13:
1140
- _g.trys.push([13, 15, , 16]);
1188
+ _p.trys.push([13, 15, , 16]);
1141
1189
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1142
1190
  case 14:
1143
- directiveText = _g.sent();
1191
+ directiveText = _p.sent();
1144
1192
  forcedDirective = extractAssistantMongoDirective(directiveText);
1145
1193
  if (forcedDirective) {
1146
1194
  directive = forcedDirective;
1147
1195
  directiveSource = 'forced';
1148
1196
  lastDirective = forcedDirective;
1197
+ recordStep('Directive resolved', {
1198
+ source: directiveSource,
1199
+ type: directive.type,
1200
+ collection: normalizeOptionalString((_m = directive.payload) === null || _m === void 0 ? void 0 : _m.collection) || undefined,
1201
+ permissionView: normalizeOptionalString((_o = directive.payload) === null || _o === void 0 ? void 0 : _o.permissionView) || undefined
1202
+ });
1149
1203
  }
1150
1204
  return [3 /*break*/, 16];
1151
1205
  case 15:
1152
- _c = _g.sent();
1206
+ _c = _p.sent();
1153
1207
  return [3 /*break*/, 16];
1154
1208
  case 16:
1155
1209
  cleanedResponseText = (directive === null || directive === void 0 ? void 0 : directive.cleaned) || responseText;
@@ -1159,18 +1213,23 @@ function executeAiAssistantCodexRun(payload, context) {
1159
1213
  if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 28];
1160
1214
  toolRequest = buildAssistantToolRequest(directive, input);
1161
1215
  progressTracker.push('Grabbing Data');
1162
- _g.label = 17;
1216
+ recordStep('Grabbing Data: start', {
1217
+ type: directive.type,
1218
+ collection: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.collection) || undefined,
1219
+ permissionView: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.permissionView) || undefined
1220
+ });
1221
+ _p.label = 17;
1163
1222
  case 17:
1164
- _g.trys.push([17, 26, , 27]);
1223
+ _p.trys.push([17, 26, , 27]);
1165
1224
  if (!(directive.type === 'aggregate')) return [3 /*break*/, 19];
1166
1225
  return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
1167
1226
  case 18:
1168
- _d = _g.sent();
1227
+ _d = _p.sent();
1169
1228
  return [3 /*break*/, 21];
1170
1229
  case 19: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
1171
1230
  case 20:
1172
- _d = _g.sent();
1173
- _g.label = 21;
1231
+ _d = _p.sent();
1232
+ _p.label = 21;
1174
1233
  case 21:
1175
1234
  toolResponse = _d;
1176
1235
  toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
@@ -1178,34 +1237,42 @@ function executeAiAssistantCodexRun(payload, context) {
1178
1237
  : null;
1179
1238
  toolPayload = buildAssistantToolResultPayload(directive, toolResponse);
1180
1239
  toolResult = toolPayload.result;
1240
+ recordStep('Grabbing Data: complete', {
1241
+ rowCount: toolPayload.result.output.rowCount,
1242
+ total: toolPayload.result.output.total,
1243
+ columns: toolPayload.result.output.columns
1244
+ });
1181
1245
  progressTracker.push('Drafting response');
1246
+ recordStep('Drafting response');
1182
1247
  followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
1183
- _g.label = 22;
1248
+ _p.label = 22;
1184
1249
  case 22:
1185
- _g.trys.push([22, 24, , 25]);
1250
+ _p.trys.push([22, 24, , 25]);
1186
1251
  return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
1187
1252
  case 23:
1188
- followupText = _g.sent();
1253
+ followupText = _p.sent();
1189
1254
  assistantContent = sanitizeAssistantResponse(followupText);
1190
1255
  return [3 /*break*/, 25];
1191
1256
  case 24:
1192
- _e = _g.sent();
1257
+ _e = _p.sent();
1193
1258
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
1194
1259
  return [3 /*break*/, 25];
1195
1260
  case 25: return [3 /*break*/, 27];
1196
1261
  case 26:
1197
- error_2 = _g.sent();
1262
+ error_2 = _p.sent();
1198
1263
  assistantContent = buildAssistantToolErrorMessage(error_2, directive, toolRequest);
1199
1264
  toolError = error_2;
1200
1265
  return [3 /*break*/, 27];
1201
1266
  case 27: return [3 /*break*/, 29];
1202
1267
  case 28:
1203
1268
  progressTracker.push('Drafting response');
1204
- _g.label = 29;
1269
+ recordStep('Drafting response');
1270
+ _p.label = 29;
1205
1271
  case 29: return [3 /*break*/, 32];
1206
1272
  case 30:
1207
- error_3 = _g.sent();
1273
+ error_3 = _p.sent();
1208
1274
  assistantContent = buildAssistantCodexErrorMessage(error_3);
1275
+ recordStep('Error', { message: normalizeOptionalString(error_3 === null || error_3 === void 0 ? void 0 : error_3.message) || 'Unknown error' });
1209
1276
  return [3 /*break*/, 32];
1210
1277
  case 31:
1211
1278
  progressTracker.stop();
@@ -1216,13 +1283,28 @@ function executeAiAssistantCodexRun(payload, context) {
1216
1283
  }
1217
1284
  finalNow = new Date();
1218
1285
  if (isSuperAdmin) {
1286
+ finishedAt = Date.now();
1219
1287
  assistantDebug = buildAssistantDebugPayload({
1220
1288
  dataQuestion: dataQuestion,
1221
1289
  directive: lastDirective,
1222
1290
  directiveSource: directiveSource,
1223
1291
  toolResult: toolResult,
1224
1292
  toolResponseDebug: toolResponseDebug,
1225
- toolError: toolError
1293
+ toolError: toolError,
1294
+ trace: {
1295
+ steps: steps,
1296
+ planning: {
1297
+ contextMode: contextMode || undefined,
1298
+ contextRoute: contextRoute || undefined,
1299
+ termHints: termHints.length ? termHints : undefined,
1300
+ collectionHints: collectionHints.length ? collectionHints : undefined
1301
+ },
1302
+ timings: {
1303
+ startedAt: new Date(runStart).toISOString(),
1304
+ finishedAt: new Date(finishedAt).toISOString(),
1305
+ totalMs: finishedAt - runStart
1306
+ }
1307
+ }
1226
1308
  });
1227
1309
  }
1228
1310
  finalMetadata = __assign(__assign(__assign({ model: resolveCodexModel() }, (requestId ? { request_id: requestId } : {})), (toolResult ? { tool_result: toolResult } : {})), (assistantDebug ? { debug: assistantDebug } : {}));
@@ -1236,16 +1318,16 @@ function executeAiAssistantCodexRun(payload, context) {
1236
1318
  }
1237
1319
  })];
1238
1320
  case 33:
1239
- _g.sent();
1240
- _g.label = 34;
1321
+ _p.sent();
1322
+ _p.label = 34;
1241
1323
  case 34: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
1242
1324
  case 35:
1243
- _g.sent();
1325
+ _p.sent();
1244
1326
  if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 37];
1245
1327
  return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
1246
1328
  case 36:
1247
- _g.sent();
1248
- _g.label = 37;
1329
+ _p.sent();
1330
+ _p.label = 37;
1249
1331
  case 37: return [2 /*return*/, finalAssistantDoc];
1250
1332
  }
1251
1333
  });
@@ -1259,7 +1341,7 @@ function executeAiAssistantCodexRun(payload, context) {
1259
1341
  }
1260
1342
  function executeAiAssistantMongoRead(payload, context) {
1261
1343
  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;
1344
+ 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, requestedFields, fieldAliases, displayDocs, priorityFields, display;
1263
1345
  var _c, _d;
1264
1346
  return __generator(this, function (_e) {
1265
1347
  switch (_e.label) {
@@ -1340,14 +1422,25 @@ function executeAiAssistantMongoRead(payload, context) {
1340
1422
  ? documents
1341
1423
  : documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
1342
1424
  includeIds = ((_d = input.options) === null || _d === void 0 ? void 0 : _d.includeIds) === true;
1343
- display = buildDisplayTable(sanitizedDocuments, {
1425
+ requestedFields = resolveProjectionRequestedFields(normalized.findOptions.projection);
1426
+ fieldAliases = resolveFieldAliases(sanitizedDocuments, requestedFields);
1427
+ displayDocs = Object.keys(fieldAliases).length
1428
+ ? applyFieldAliasesForDisplay(sanitizedDocuments, fieldAliases)
1429
+ : sanitizedDocuments;
1430
+ priorityFields = requestedFields.length
1431
+ ? __spreadArray(__spreadArray([], __read(requestedFields), false), __read(AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS), false) : AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS;
1432
+ display = buildDisplayTable(displayDocs, {
1344
1433
  includeIds: includeIds,
1345
1434
  maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
1346
- maxRows: normalized.findOptions.limit
1435
+ maxRows: normalized.findOptions.limit,
1436
+ priorityFields: priorityFields
1347
1437
  });
1348
1438
  if (total !== null) {
1349
1439
  display.total = total;
1350
1440
  }
1441
+ if (Object.keys(fieldAliases).length) {
1442
+ fallbackMeta.fieldAliases = fieldAliases;
1443
+ }
1351
1444
  return [2 /*return*/, __assign({ documents: sanitizedDocuments, total: total, display: display }, (isSuperAdmin ? {
1352
1445
  debug: {
1353
1446
  collection: collection,
@@ -1736,7 +1829,7 @@ function buildAssistantDebugPayload(params) {
1736
1829
  notes.push("Tool error: ".concat(errorMessage));
1737
1830
  }
1738
1831
  }
1739
- return {
1832
+ var payload = {
1740
1833
  decision: {
1741
1834
  dataQuestion: params.dataQuestion,
1742
1835
  directiveSource: params.directiveSource
@@ -1760,6 +1853,10 @@ function buildAssistantDebugPayload(params) {
1760
1853
  fallbacks: ((_t = params.toolResponseDebug) === null || _t === void 0 ? void 0 : _t.fallbacks) || undefined,
1761
1854
  notes: notes
1762
1855
  };
1856
+ if (params.trace && typeof params.trace === 'object') {
1857
+ payload.trace = params.trace;
1858
+ }
1859
+ return payload;
1763
1860
  }
1764
1861
  function buildAssistantToolErrorMessage(error, directive, request) {
1765
1862
  var _a, _b;
@@ -2009,6 +2106,219 @@ function normalizeColumnPriorityKey(column) {
2009
2106
  var base = trimmed.includes('.') ? trimmed.split('.').pop() || trimmed : trimmed;
2010
2107
  return base.toLowerCase();
2011
2108
  }
2109
+ function tokenizeFieldKey(value) {
2110
+ var normalized = String(value || '')
2111
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
2112
+ .replace(/[^a-zA-Z0-9]+/g, ' ')
2113
+ .trim()
2114
+ .toLowerCase();
2115
+ return normalized ? normalized.split(/\s+/).filter(Boolean) : [];
2116
+ }
2117
+ function normalizeFieldMatchKey(value) {
2118
+ return tokenizeFieldKey(value).join('');
2119
+ }
2120
+ function getValueAtPath(obj, path) {
2121
+ var e_1, _a;
2122
+ if (!obj || typeof obj !== 'object') {
2123
+ return undefined;
2124
+ }
2125
+ var parts = String(path || '').split('.').filter(Boolean);
2126
+ var current = obj;
2127
+ try {
2128
+ for (var parts_1 = __values(parts), parts_1_1 = parts_1.next(); !parts_1_1.done; parts_1_1 = parts_1.next()) {
2129
+ var part = parts_1_1.value;
2130
+ if (!current || typeof current !== 'object') {
2131
+ return undefined;
2132
+ }
2133
+ current = current[part];
2134
+ }
2135
+ }
2136
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
2137
+ finally {
2138
+ try {
2139
+ if (parts_1_1 && !parts_1_1.done && (_a = parts_1.return)) _a.call(parts_1);
2140
+ }
2141
+ finally { if (e_1) throw e_1.error; }
2142
+ }
2143
+ return current;
2144
+ }
2145
+ function hasNonEmptyValue(docs, fieldPath, options) {
2146
+ var e_2, _a;
2147
+ if (!Array.isArray(docs) || !fieldPath) {
2148
+ return false;
2149
+ }
2150
+ var usePath = fieldPath.includes('.');
2151
+ try {
2152
+ for (var docs_1 = __values(docs), docs_1_1 = docs_1.next(); !docs_1_1.done; docs_1_1 = docs_1.next()) {
2153
+ var doc = docs_1_1.value;
2154
+ var value = usePath ? getValueAtPath(doc, fieldPath) : doc === null || doc === void 0 ? void 0 : doc[fieldPath];
2155
+ if ((options === null || options === void 0 ? void 0 : options.treatObjectLikeAsEmpty) && isDisplayObjectLike(value)) {
2156
+ continue;
2157
+ }
2158
+ if (!isEmptyDisplayValue(value)) {
2159
+ return true;
2160
+ }
2161
+ }
2162
+ }
2163
+ catch (e_2_1) { e_2 = { error: e_2_1 }; }
2164
+ finally {
2165
+ try {
2166
+ if (docs_1_1 && !docs_1_1.done && (_a = docs_1.return)) _a.call(docs_1);
2167
+ }
2168
+ finally { if (e_2) throw e_2.error; }
2169
+ }
2170
+ return false;
2171
+ }
2172
+ function collectFieldCandidates(docs) {
2173
+ var candidates = new Map();
2174
+ if (!Array.isArray(docs)) {
2175
+ return candidates;
2176
+ }
2177
+ var addCandidate = function (path, value) {
2178
+ if (!path) {
2179
+ return;
2180
+ }
2181
+ var entry = candidates.get(path) || {
2182
+ nonEmpty: 0,
2183
+ objectLike: 0,
2184
+ normalized: normalizeFieldMatchKey(path)
2185
+ };
2186
+ if (!isEmptyDisplayValue(value)) {
2187
+ entry.nonEmpty += 1;
2188
+ }
2189
+ if (isDisplayObjectLike(value)) {
2190
+ entry.objectLike += 1;
2191
+ }
2192
+ candidates.set(path, entry);
2193
+ };
2194
+ docs.forEach(function (doc) {
2195
+ if (!doc || typeof doc !== 'object') {
2196
+ return;
2197
+ }
2198
+ Object.keys(doc).forEach(function (key) {
2199
+ if (!key) {
2200
+ return;
2201
+ }
2202
+ var value = doc[key];
2203
+ addCandidate(key, value);
2204
+ if (isPlainObject(value) && !isMongoObjectId(value) && !(value instanceof Date)) {
2205
+ var nestedKeys = Object.keys(value).slice(0, 50);
2206
+ nestedKeys.forEach(function (nestedKey) {
2207
+ if (!nestedKey) {
2208
+ return;
2209
+ }
2210
+ addCandidate("".concat(key, ".").concat(nestedKey), value[nestedKey]);
2211
+ });
2212
+ }
2213
+ });
2214
+ });
2215
+ return candidates;
2216
+ }
2217
+ function resolveFieldAliases(docs, requestedFields) {
2218
+ var aliases = {};
2219
+ if (!Array.isArray(docs) || !requestedFields.length) {
2220
+ return aliases;
2221
+ }
2222
+ var missing = requestedFields.filter(function (field) { return field && !hasNonEmptyValue(docs, field, { treatObjectLikeAsEmpty: true }); });
2223
+ if (!missing.length) {
2224
+ return aliases;
2225
+ }
2226
+ var candidates = collectFieldCandidates(docs);
2227
+ missing.forEach(function (field) {
2228
+ var normalizedRequested = normalizeFieldMatchKey(field);
2229
+ if (!normalizedRequested) {
2230
+ return;
2231
+ }
2232
+ var bestPath = '';
2233
+ var bestScore = 0;
2234
+ candidates.forEach(function (stats, path) {
2235
+ if (!path || stats.nonEmpty === 0) {
2236
+ return;
2237
+ }
2238
+ if (isAssistantIdField(path)) {
2239
+ return;
2240
+ }
2241
+ var normalizedCandidate = stats.normalized || normalizeFieldMatchKey(path);
2242
+ if (!normalizedCandidate) {
2243
+ return;
2244
+ }
2245
+ var score = 0;
2246
+ if (normalizedCandidate === normalizedRequested) {
2247
+ score = 100;
2248
+ }
2249
+ else if (normalizedCandidate.includes(normalizedRequested) || normalizedRequested.includes(normalizedCandidate)) {
2250
+ score = 70;
2251
+ }
2252
+ else {
2253
+ var candidateTokens_1 = tokenizeFieldKey(path);
2254
+ var requestedTokens = tokenizeFieldKey(field);
2255
+ var overlap = requestedTokens.filter(function (token) { return candidateTokens_1.includes(token); }).length;
2256
+ if (overlap > 0) {
2257
+ score = 40 + overlap * 5;
2258
+ }
2259
+ }
2260
+ var objectRatio = stats.objectLike / Math.max(stats.nonEmpty, 1);
2261
+ if (objectRatio > 0.5) {
2262
+ score -= 50;
2263
+ }
2264
+ if (score > bestScore) {
2265
+ bestScore = score;
2266
+ bestPath = path;
2267
+ }
2268
+ });
2269
+ if (bestPath && bestScore >= 60) {
2270
+ aliases[field] = bestPath;
2271
+ }
2272
+ });
2273
+ return aliases;
2274
+ }
2275
+ function applyFieldAliasesForDisplay(docs, aliases) {
2276
+ if (!Array.isArray(docs) || !aliases || !Object.keys(aliases).length) {
2277
+ return docs;
2278
+ }
2279
+ return docs.map(function (doc) {
2280
+ var next = __assign({}, doc);
2281
+ Object.keys(aliases).forEach(function (targetField) {
2282
+ var sourcePath = aliases[targetField];
2283
+ if (!sourcePath) {
2284
+ return;
2285
+ }
2286
+ var existing = targetField.includes('.') ? getValueAtPath(doc, targetField) : doc === null || doc === void 0 ? void 0 : doc[targetField];
2287
+ if (!isEmptyDisplayValue(existing)) {
2288
+ return;
2289
+ }
2290
+ var value = getValueAtPath(doc, sourcePath);
2291
+ if (value !== undefined) {
2292
+ next[targetField] = value;
2293
+ }
2294
+ });
2295
+ return next;
2296
+ });
2297
+ }
2298
+ function resolveProjectionRequestedFields(projection) {
2299
+ if (!projection || typeof projection !== 'object') {
2300
+ return [];
2301
+ }
2302
+ var keys = Object.keys(projection);
2303
+ if (!keys.length) {
2304
+ return [];
2305
+ }
2306
+ var hasInclude = false;
2307
+ var hasExclude = false;
2308
+ keys.forEach(function (key) {
2309
+ var value = projection[key];
2310
+ if (value === 0 || value === false) {
2311
+ hasExclude = true;
2312
+ }
2313
+ else if (value === 1 || value === true) {
2314
+ hasInclude = true;
2315
+ }
2316
+ });
2317
+ if (!hasInclude || hasExclude) {
2318
+ return [];
2319
+ }
2320
+ return keys.filter(function (key) { return !isAssistantIdField(key); });
2321
+ }
2012
2322
  function formatDisplayColumnName(column) {
2013
2323
  var trimmed = String(column || '').trim();
2014
2324
  if (!trimmed) {
@@ -2027,7 +2337,22 @@ function formatDisplayColumnName(column) {
2027
2337
  if (normalized === 'updatedat') {
2028
2338
  return 'Updated At';
2029
2339
  }
2030
- return trimmed;
2340
+ var parts = trimmed.split('.');
2341
+ var base = parts[parts.length - 1] || trimmed;
2342
+ if ((base === 'name' || base === 'title' || base === 'label') && parts.length > 1) {
2343
+ return parts[parts.length - 2]
2344
+ .replace(/[_-]+/g, ' ')
2345
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
2346
+ .replace(/\s+/g, ' ')
2347
+ .trim()
2348
+ .replace(/\b\w/g, function (char) { return char.toUpperCase(); });
2349
+ }
2350
+ return base
2351
+ .replace(/[_-]+/g, ' ')
2352
+ .replace(/([a-z0-9])([A-Z])/g, '$1 $2')
2353
+ .replace(/\s+/g, ' ')
2354
+ .trim()
2355
+ .replace(/\b\w/g, function (char) { return char.toUpperCase(); });
2031
2356
  }
2032
2357
  function truncateDisplayText(value, maxLength) {
2033
2358
  if (maxLength === void 0) { maxLength = AI_ASSISTANT_DISPLAY_STRING_LIMIT; }
@@ -2523,7 +2848,7 @@ function matchContainsField(value, field) {
2523
2848
  });
2524
2849
  }
2525
2850
  function resolveAggregateCompletionFallback(pipeline) {
2526
- var e_1, _a;
2851
+ var e_3, _a;
2527
2852
  if (!Array.isArray(pipeline)) {
2528
2853
  return null;
2529
2854
  }
@@ -2536,7 +2861,7 @@ function resolveAggregateCompletionFallback(pipeline) {
2536
2861
  }
2537
2862
  var addFields = stage.$addFields;
2538
2863
  try {
2539
- for (var _b = (e_1 = void 0, __values(Object.keys(addFields))), _c = _b.next(); !_c.done; _c = _b.next()) {
2864
+ for (var _b = (e_3 = void 0, __values(Object.keys(addFields))), _c = _b.next(); !_c.done; _c = _b.next()) {
2540
2865
  var key = _c.value;
2541
2866
  if (!isCompletionFieldName(key)) {
2542
2867
  continue;
@@ -2550,12 +2875,12 @@ function resolveAggregateCompletionFallback(pipeline) {
2550
2875
  }
2551
2876
  }
2552
2877
  }
2553
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2878
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
2554
2879
  finally {
2555
2880
  try {
2556
2881
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2557
2882
  }
2558
- finally { if (e_1) throw e_1.error; }
2883
+ finally { if (e_3) throw e_3.error; }
2559
2884
  }
2560
2885
  if (candidateField) {
2561
2886
  break;
@@ -2922,6 +3247,27 @@ function tokenizeCollectionText(value) {
2922
3247
  });
2923
3248
  return Array.from(new Set(tokens));
2924
3249
  }
3250
+ function expandAssistantTermSynonyms(text) {
3251
+ var base = normalizeOptionalString(text);
3252
+ if (!base) {
3253
+ return { expanded: '', matches: [] };
3254
+ }
3255
+ var expanded = base;
3256
+ var matches = [];
3257
+ AI_ASSISTANT_TERM_SYNONYMS.forEach(function (entry) {
3258
+ if (!entry.pattern.test(base)) {
3259
+ return;
3260
+ }
3261
+ var existing = expanded.toLowerCase();
3262
+ entry.expansions.forEach(function (expansion) {
3263
+ if (expansion && !existing.includes(expansion.toLowerCase())) {
3264
+ expanded = "".concat(expanded, " ").concat(expansion);
3265
+ }
3266
+ });
3267
+ matches.push({ term: entry.label, expansions: entry.expansions });
3268
+ });
3269
+ return { expanded: expanded, matches: matches };
3270
+ }
2925
3271
  function listAssistantCollections(db, dbName) {
2926
3272
  return __awaiter(this, void 0, void 0, function () {
2927
3273
  var cacheKey, cached, now, collections, names, _a;
@@ -3053,7 +3399,7 @@ function resolveAssistantCollectionHints(message, dbName, db) {
3053
3399
  });
3054
3400
  }
3055
3401
  function findQueryDateField(query) {
3056
- var e_2, _a, e_3, _b;
3402
+ var e_4, _a, e_5, _b;
3057
3403
  if (!query || typeof query !== 'object') {
3058
3404
  return null;
3059
3405
  }
@@ -3067,12 +3413,12 @@ function findQueryDateField(query) {
3067
3413
  }
3068
3414
  }
3069
3415
  }
3070
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
3416
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
3071
3417
  finally {
3072
3418
  try {
3073
3419
  if (query_1_1 && !query_1_1.done && (_a = query_1.return)) _a.call(query_1);
3074
3420
  }
3075
- finally { if (e_2) throw e_2.error; }
3421
+ finally { if (e_4) throw e_4.error; }
3076
3422
  }
3077
3423
  return null;
3078
3424
  }
@@ -3091,12 +3437,12 @@ function findQueryDateField(query) {
3091
3437
  }
3092
3438
  }
3093
3439
  }
3094
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
3440
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
3095
3441
  finally {
3096
3442
  try {
3097
3443
  if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
3098
3444
  }
3099
- finally { if (e_3) throw e_3.error; }
3445
+ finally { if (e_5) throw e_5.error; }
3100
3446
  }
3101
3447
  return null;
3102
3448
  }
@@ -3126,7 +3472,7 @@ function resolveQueryDateFieldFallback(query) {
3126
3472
  return { from: dateField, to: fallback };
3127
3473
  }
3128
3474
  function containsForbiddenMongoOperators(value) {
3129
- var e_4, _a;
3475
+ var e_6, _a;
3130
3476
  if (!value || typeof value !== 'object') {
3131
3477
  return false;
3132
3478
  }
@@ -3145,12 +3491,12 @@ function containsForbiddenMongoOperators(value) {
3145
3491
  }
3146
3492
  }
3147
3493
  }
3148
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
3494
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
3149
3495
  finally {
3150
3496
  try {
3151
3497
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3152
3498
  }
3153
- finally { if (e_4) throw e_4.error; }
3499
+ finally { if (e_6) throw e_6.error; }
3154
3500
  }
3155
3501
  return false;
3156
3502
  }
@@ -3384,8 +3730,8 @@ function applyCodexStreamStatusHandler(runOptions, streamStatusHandler) {
3384
3730
  }
3385
3731
  function waitForCodexWorkerMessage(worker, streamStatusHandler) {
3386
3732
  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;
3733
+ var _a, _b, _c, _d, message, payload, status_1, e_7_1;
3734
+ var _e, e_7, _f, _g;
3389
3735
  return __generator(this, function (_h) {
3390
3736
  switch (_h.label) {
3391
3737
  case 0:
@@ -3412,8 +3758,8 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
3412
3758
  return [3 /*break*/, 1];
3413
3759
  case 4: return [3 /*break*/, 11];
3414
3760
  case 5:
3415
- e_5_1 = _h.sent();
3416
- e_5 = { error: e_5_1 };
3761
+ e_7_1 = _h.sent();
3762
+ e_7 = { error: e_7_1 };
3417
3763
  return [3 /*break*/, 11];
3418
3764
  case 6:
3419
3765
  _h.trys.push([6, , 9, 10]);
@@ -3424,7 +3770,7 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
3424
3770
  _h.label = 8;
3425
3771
  case 8: return [3 /*break*/, 10];
3426
3772
  case 9:
3427
- if (e_5) throw e_5.error;
3773
+ if (e_7) throw e_7.error;
3428
3774
  return [7 /*endfinally*/];
3429
3775
  case 10: return [7 /*endfinally*/];
3430
3776
  case 11: throw new CodexWorkerBootstrapError('Codex worker exited before completing.');
@@ -3776,6 +4122,12 @@ function buildAssistantContext(input, userContext) {
3776
4122
  if (collectionHints.length) {
3777
4123
  lines.push("Collection hints: ".concat(collectionHints.join(', ')));
3778
4124
  }
4125
+ var termHints = Array.isArray(userContext === null || userContext === void 0 ? void 0 : userContext.termHints)
4126
+ ? userContext === null || userContext === void 0 ? void 0 : userContext.termHints.filter(Boolean)
4127
+ : [];
4128
+ if (termHints.length) {
4129
+ lines.push("Term hints: ".concat(termHints.join('; ')));
4130
+ }
3779
4131
  var mongoDb = normalizeOptionalString((_c = input === null || input === void 0 ? void 0 : input.mongo) === null || _c === void 0 ? void 0 : _c.database);
3780
4132
  var mongoDbs = Array.isArray((_d = input === null || input === void 0 ? void 0 : input.mongo) === null || _d === void 0 ? void 0 : _d.databases)
3781
4133
  ? input.mongo.databases.map(function (value) { return normalizeOptionalString(value); }).filter(Boolean)
@@ -3806,7 +4158,7 @@ function normalizeRouteMatchKey(value) {
3806
4158
  return normalizeRouteKey(value).toLowerCase();
3807
4159
  }
3808
4160
  function buildClientRouteIndex() {
3809
- var e_6, _a;
4161
+ var e_8, _a;
3810
4162
  var _b;
3811
4163
  var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
3812
4164
  var set = new Set();
@@ -3825,12 +4177,12 @@ function buildClientRouteIndex() {
3825
4177
  }
3826
4178
  }
3827
4179
  }
3828
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
4180
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
3829
4181
  finally {
3830
4182
  try {
3831
4183
  if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
3832
4184
  }
3833
- finally { if (e_6) throw e_6.error; }
4185
+ finally { if (e_8) throw e_8.error; }
3834
4186
  }
3835
4187
  return { set: set, map: map, size: routes.length };
3836
4188
  }
@@ -3956,7 +4308,7 @@ function sanitizeAssistantResponse(value) {
3956
4308
  return normalizeAssistantRoutes(normalizedCurrency);
3957
4309
  }
3958
4310
  function evaluateAssistantGuardrails(message) {
3959
- var e_7, _a;
4311
+ var e_9, _a;
3960
4312
  var normalized = String(message || '').toLowerCase();
3961
4313
  var patterns = [
3962
4314
  {
@@ -4002,12 +4354,12 @@ function evaluateAssistantGuardrails(message) {
4002
4354
  }
4003
4355
  }
4004
4356
  }
4005
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
4357
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
4006
4358
  finally {
4007
4359
  try {
4008
4360
  if (patterns_1_1 && !patterns_1_1.done && (_a = patterns_1.return)) _a.call(patterns_1);
4009
4361
  }
4010
- finally { if (e_7) throw e_7.error; }
4362
+ finally { if (e_9) throw e_9.error; }
4011
4363
  }
4012
4364
  return null;
4013
4365
  }
@@ -4171,8 +4523,8 @@ function handleCodexUpload(id_conversation, file_name, content_base64, size, con
4171
4523
  }
4172
4524
  function readAttachmentContents(attachments) {
4173
4525
  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;
4526
+ var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_10_1;
4527
+ var e_10, _b;
4176
4528
  return __generator(this, function (_c) {
4177
4529
  switch (_c.label) {
4178
4530
  case 0:
@@ -4251,14 +4603,14 @@ function readAttachmentContents(attachments) {
4251
4603
  return [3 /*break*/, 2];
4252
4604
  case 10: return [3 /*break*/, 13];
4253
4605
  case 11:
4254
- e_8_1 = _c.sent();
4255
- e_8 = { error: e_8_1 };
4606
+ e_10_1 = _c.sent();
4607
+ e_10 = { error: e_10_1 };
4256
4608
  return [3 /*break*/, 13];
4257
4609
  case 12:
4258
4610
  try {
4259
4611
  if (attachments_1_1 && !attachments_1_1.done && (_b = attachments_1.return)) _b.call(attachments_1);
4260
4612
  }
4261
- finally { if (e_8) throw e_8.error; }
4613
+ finally { if (e_10) throw e_10.error; }
4262
4614
  return [7 /*endfinally*/];
4263
4615
  case 13: return [2 /*return*/, {
4264
4616
  promptText: chunks.length ? "\n\nAttachments:\n".concat(chunks.join('\n\n')) : '',
@@ -4435,7 +4787,7 @@ function estimateUsage(messages, responseText, model) {
4435
4787
  };
4436
4788
  }
4437
4789
  function evaluateGuardrails(message) {
4438
- var e_9, _a;
4790
+ var e_11, _a;
4439
4791
  var normalized = String(message || '').toLowerCase();
4440
4792
  var patterns = [
4441
4793
  { 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 +4809,12 @@ function evaluateGuardrails(message) {
4457
4809
  }
4458
4810
  }
4459
4811
  }
4460
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
4812
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
4461
4813
  finally {
4462
4814
  try {
4463
4815
  if (patterns_2_1 && !patterns_2_1.done && (_a = patterns_2.return)) _a.call(patterns_2);
4464
4816
  }
4465
- finally { if (e_9) throw e_9.error; }
4817
+ finally { if (e_11) throw e_11.error; }
4466
4818
  }
4467
4819
  return null;
4468
4820
  }