@resolveio/server-lib 20.15.5 → 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.
@@ -142,10 +142,11 @@ var AI_ASSISTANT_TOOL_MAX_STEPS = 1;
142
142
  var AI_ASSISTANT_DISPLAY_MAX_COLUMNS = 12;
143
143
  var AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS = 20;
144
144
  var AI_ASSISTANT_DISPLAY_STRING_LIMIT = 160;
145
- var AI_ASSISTANT_PROGRESS_PLACEHOLDER = 'Thinking...';
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
148
  var AI_ASSISTANT_PROGRESS_TICKS = [
149
+ 'Grabbing Data',
149
150
  'Drafting response'
150
151
  ];
151
152
  var AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS = [
@@ -245,6 +246,13 @@ var AI_ASSISTANT_COLLECTION_STOPWORDS = new Set([
245
246
  'missing',
246
247
  'overdue'
247
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
+ ];
248
256
  var AI_ASSISTANT_SYSTEM_PROMPT = [
249
257
  'You are the ResolveIO in-app AI assistant running with read-only access to the codebase.',
250
258
  'Core rules:',
@@ -256,7 +264,9 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
256
264
  '- Do not assist with hacking, bypassing security, or abuse.',
257
265
  'Accuracy & tools:',
258
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.',
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.',
259
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.',
260
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.',
261
271
  '- Prefer running a small Mongo read over asking multiple questions.',
262
272
  '- For any data request (counts, lists, breakdowns, recent/last items), you MUST run a MONGO_READ or MONGO_AGG before answering.',
@@ -264,13 +274,16 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
264
274
  '- If a field starts with id_ and refers to another collection, treat it as a foreign key and look up the related record when needed.',
265
275
  '- When the user provides a customer, well, or chemical name, use case-insensitive regex matching to find it. Assume the name exists and try to match it before asking questions.',
266
276
  '- Use the codebase context to choose correct collections/fields/workflows and use MONGO_READ/MONGO_AGG to answer with real data when needed.',
277
+ '- Process (fast path): Queue -> Planning -> Grabbing Data -> Drafting response. Use regex/keyword matching to identify collections/models, draft a minimal query, run the tool, then format a table. This should be fast; avoid extra narration.',
267
278
  '- Assume a relevant collection exists; if verification reads return zero data, report no data found instead of interrogating the user.',
279
+ '- Never claim "no data exists" unless you resolved a collection and executed a legitimate query (with fallback date fields when needed) that returned zero rows.',
268
280
  '- For direct questions, answer first. Ask a single follow-up only if required to proceed.',
269
281
  'Data Presentation:',
270
282
  '- Output plain Markdown (NO triple backticks).',
271
283
  '- When you reference database results, summarize first, then include a Markdown table.',
272
284
  '- When presenting record lists or aggregates, produce a Markdown table (pipes).',
273
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.',
274
287
  '- Do not include `_id` & `__v` & `id_<other collection _id property>` in tables by default.',
275
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.',
276
289
  '- Rename `createdAt` to `Created At` and `updatedAt` to `Updated At` in tables.',
@@ -308,6 +321,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
308
321
  '- Only request data when the user has permission for that module; invoice data requires invoice view access.',
309
322
  '- If the user lacks permission, answer without data and explain how to view it in the app or request access.',
310
323
  '- For simple counts or time-range totals, use MONGO_READ (includeTotal). For breakdowns, rankings, or sums grouped by a field, use MONGO_AGG.',
324
+ '- For performance, keep pipelines minimal: avoid $push arrays or large fields unless the user explicitly asks for them.',
311
325
  '- For completion metrics (ex: "completed per day"), filter by completed status when applicable and use completion date fields; if completion dates are missing, fall back to createdAt/date_created and note the fallback.',
312
326
  '- Before issuing MONGO_READ or MONGO_AGG, verify the collection name and key fields by checking collection/model definitions in the current app (look for "collectionName:" and date fields like date_created/date_completed/createdAt). Do not invent collection names.',
313
327
  '- For creation-date questions when both date_created and createdAt exist, match both with $or so results are not missed.',
@@ -327,6 +341,76 @@ var AI_FORM_PATCH_SYSTEM_PROMPT = [
327
341
  '- Use medium reasoning effort.'
328
342
  ].join('\n');
329
343
  var assistantCodexClient = null;
344
+ var assistantCodexRunQueue = [];
345
+ var assistantCodexRunDraining = false;
346
+ /* eslint-enable no-unused-vars */
347
+ function enqueueAssistantCodexRun(task) {
348
+ var _this = this;
349
+ assistantCodexRunQueue.push(task);
350
+ if (assistantCodexRunDraining) {
351
+ return;
352
+ }
353
+ assistantCodexRunDraining = true;
354
+ queueMicrotask(function () { return __awaiter(_this, void 0, void 0, function () {
355
+ return __generator(this, function (_a) {
356
+ switch (_a.label) {
357
+ case 0: return [4 /*yield*/, drainAssistantCodexRunQueue()];
358
+ case 1:
359
+ _a.sent();
360
+ return [2 /*return*/];
361
+ }
362
+ });
363
+ }); });
364
+ }
365
+ function drainAssistantCodexRunQueue() {
366
+ return __awaiter(this, void 0, void 0, function () {
367
+ var next, error_1;
368
+ var _this = this;
369
+ return __generator(this, function (_a) {
370
+ switch (_a.label) {
371
+ case 0:
372
+ _a.trys.push([0, , 7, 8]);
373
+ _a.label = 1;
374
+ case 1:
375
+ if (!assistantCodexRunQueue.length) return [3 /*break*/, 6];
376
+ next = assistantCodexRunQueue.shift();
377
+ if (!next) {
378
+ return [3 /*break*/, 1];
379
+ }
380
+ _a.label = 2;
381
+ case 2:
382
+ _a.trys.push([2, 4, , 5]);
383
+ return [4 /*yield*/, next()];
384
+ case 3:
385
+ _a.sent();
386
+ return [3 /*break*/, 5];
387
+ case 4:
388
+ error_1 = _a.sent();
389
+ console.error(new Date(), 'AI assistant run failed:', error_1);
390
+ return [3 /*break*/, 5];
391
+ case 5: return [3 /*break*/, 1];
392
+ case 6: return [3 /*break*/, 8];
393
+ case 7:
394
+ assistantCodexRunDraining = false;
395
+ if (assistantCodexRunQueue.length) {
396
+ assistantCodexRunDraining = true;
397
+ queueMicrotask(function () { return __awaiter(_this, void 0, void 0, function () {
398
+ return __generator(this, function (_a) {
399
+ switch (_a.label) {
400
+ case 0: return [4 /*yield*/, drainAssistantCodexRunQueue()];
401
+ case 1:
402
+ _a.sent();
403
+ return [2 /*return*/];
404
+ }
405
+ });
406
+ }); });
407
+ }
408
+ return [7 /*endfinally*/];
409
+ case 8: return [2 /*return*/];
410
+ }
411
+ });
412
+ });
413
+ }
330
414
  function loadAiTerminalMethods(methodManager) {
331
415
  methodManager.methods({
332
416
  aiTerminalConversationCreate: {
@@ -854,10 +938,11 @@ function executeAiFormPatch(payload, context) {
854
938
  }
855
939
  function executeAiAssistantCodexRun(payload, context) {
856
940
  return __awaiter(this, void 0, void 0, function () {
857
- var input, message, requestId, guardrail, conversation_2, now_2, userMsg, assistantMsg, user, isSuperAdmin, hasInvoiceAccess, customerId, conversation, now, attachments, attachmentData, historyLimit, history, _a, historyLines, collectionHints, dbName, db, hintText, _b, assistantContext, prompt, workspaceRoot, codexConfig, runOptions, userDoc, initialProgress, assistantDoc, insertResult, assistantMessageId, progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, dataQuestion, lastDirective, toolResponseDebug, toolError, responseText, directive, directiveSourceText, directivePrompt, directiveText, forcedDirective, _c, cleanedResponseText, toolRequest, toolResponse, _d, toolPayload, followupPrompt, followupText, _e, error_1, error_2, finalNow, finalMetadata, finalAssistantDoc;
858
- var _f, _g, _h;
859
- return __generator(this, function (_j) {
860
- switch (_j.label) {
941
+ var input, message, requestId, guardrail, conversation_2, now_2, userMsg, assistantMsg, user, isSuperAdmin, hasInvoiceAccess, customerId, conversation, now, attachments, attachmentData, historyLimit, history, _a, historyLines, userDoc, initialProgress, assistantDoc, insertResult, assistantMessageId;
942
+ var _this = this;
943
+ var _b, _c;
944
+ return __generator(this, function (_d) {
945
+ switch (_d.label) {
861
946
  case 0:
862
947
  input = payload || {};
863
948
  message = normalizeOptionalString(input.message);
@@ -872,7 +957,7 @@ function executeAiAssistantCodexRun(payload, context) {
872
957
  if (!(guardrail === null || guardrail === void 0 ? void 0 : guardrail.blocked)) return [3 /*break*/, 5];
873
958
  return [4 /*yield*/, ensureConversation(input, 'codex')];
874
959
  case 1:
875
- conversation_2 = _j.sent();
960
+ conversation_2 = _d.sent();
876
961
  now_2 = new Date();
877
962
  userMsg = {
878
963
  id_conversation: conversation_2._id,
@@ -892,13 +977,13 @@ function executeAiAssistantCodexRun(payload, context) {
892
977
  };
893
978
  return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userMsg)];
894
979
  case 2:
895
- _j.sent();
980
+ _d.sent();
896
981
  return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(assistantMsg)];
897
982
  case 3:
898
- _j.sent();
983
+ _d.sent();
899
984
  return [4 /*yield*/, touchConversation(conversation_2._id, now_2)];
900
985
  case 4:
901
- _j.sent();
986
+ _d.sent();
902
987
  return [2 /*return*/, {
903
988
  conversation: conversation_2,
904
989
  message: assistantMsg,
@@ -906,27 +991,27 @@ function executeAiAssistantCodexRun(payload, context) {
906
991
  }];
907
992
  case 5: return [4 /*yield*/, user_collection_1.Users.findById(context === null || context === void 0 ? void 0 : context.id_user)];
908
993
  case 6:
909
- user = _j.sent();
910
- isSuperAdmin = !!((_f = user === null || user === void 0 ? void 0 : user.roles) === null || _f === void 0 ? void 0 : _f.super_admin);
994
+ user = _d.sent();
995
+ isSuperAdmin = !!((_b = user === null || user === void 0 ? void 0 : user.roles) === null || _b === void 0 ? void 0 : _b.super_admin);
911
996
  hasInvoiceAccess = userHasInvoiceAccess(user);
912
- customerId = normalizeOptionalString((_g = user === null || user === void 0 ? void 0 : user.other) === null || _g === void 0 ? void 0 : _g.id_customer);
997
+ customerId = normalizeOptionalString((_c = user === null || user === void 0 ? void 0 : user.other) === null || _c === void 0 ? void 0 : _c.id_customer);
913
998
  return [4 /*yield*/, ensureConversation(input, 'codex')];
914
999
  case 7:
915
- conversation = _j.sent();
1000
+ conversation = _d.sent();
916
1001
  now = new Date();
917
1002
  attachments = Array.isArray(input.attachments) ? input.attachments : [];
918
1003
  return [4 /*yield*/, readAttachmentContents(attachments)];
919
1004
  case 8:
920
- attachmentData = _j.sent();
1005
+ attachmentData = _d.sent();
921
1006
  historyLimit = normalizeHistoryLimit(input.max_history);
922
1007
  if (!(historyLimit > 0)) return [3 /*break*/, 10];
923
1008
  return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.find({ id_conversation: conversation._id, role: { $in: ['user', 'assistant'] } }, { sort: { createdAt: 1 }, limit: historyLimit * 2 })];
924
1009
  case 9:
925
- _a = _j.sent();
1010
+ _a = _d.sent();
926
1011
  return [3 /*break*/, 11];
927
1012
  case 10:
928
1013
  _a = [];
929
- _j.label = 11;
1014
+ _d.label = 11;
930
1015
  case 11:
931
1016
  history = _a;
932
1017
  historyLines = [];
@@ -937,49 +1022,6 @@ function executeAiAssistantCodexRun(payload, context) {
937
1022
  historyLines.push("".concat(role, ": ").concat(content));
938
1023
  }
939
1024
  });
940
- collectionHints = [];
941
- _j.label = 12;
942
- case 12:
943
- _j.trys.push([12, 14, , 15]);
944
- dbName = resolveAssistantDatabaseName(undefined, input.mongo);
945
- db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
946
- hintText = [
947
- message,
948
- normalizeOptionalString((_h = input === null || input === void 0 ? void 0 : input.context) === null || _h === void 0 ? void 0 : _h.route)
949
- ].filter(Boolean).join(' ');
950
- return [4 /*yield*/, resolveAssistantCollectionHints(hintText, dbName, db)];
951
- case 13:
952
- collectionHints = _j.sent();
953
- return [3 /*break*/, 15];
954
- case 14:
955
- _b = _j.sent();
956
- collectionHints = [];
957
- return [3 /*break*/, 15];
958
- case 15:
959
- assistantContext = buildAssistantContext(input, {
960
- isSuperAdmin: isSuperAdmin,
961
- hasInvoiceAccess: hasInvoiceAccess,
962
- customerId: customerId,
963
- collectionHints: collectionHints
964
- });
965
- prompt = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
966
- return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
967
- case 16:
968
- workspaceRoot = _j.sent();
969
- codexConfig = resolveCodexSettings();
970
- runOptions = {
971
- timeoutMs: resolveCodexTimeoutMs(),
972
- threadOptions: {
973
- workingDirectory: workspaceRoot,
974
- sandboxMode: 'read-only',
975
- skipGitRepoCheck: true,
976
- modelReasoningEffort: resolveCodexThoughtLevel(),
977
- networkAccessEnabled: false,
978
- webSearchMode: 'disabled',
979
- webSearchEnabled: false,
980
- approvalPolicy: 'never'
981
- }
982
- };
983
1025
  userDoc = {
984
1026
  id_conversation: conversation._id,
985
1027
  role: 'user',
@@ -989,7 +1031,7 @@ function executeAiAssistantCodexRun(payload, context) {
989
1031
  createdAt: now,
990
1032
  updatedAt: now
991
1033
  };
992
- initialProgress = ['Thinking'];
1034
+ initialProgress = ['Planning'];
993
1035
  assistantDoc = {
994
1036
  id_conversation: conversation._id,
995
1037
  role: 'assistant',
@@ -999,154 +1041,307 @@ function executeAiAssistantCodexRun(payload, context) {
999
1041
  updatedAt: now
1000
1042
  };
1001
1043
  return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userDoc)];
1002
- case 17:
1003
- _j.sent();
1044
+ case 12:
1045
+ _d.sent();
1004
1046
  return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(assistantDoc)];
1005
- case 18:
1006
- insertResult = _j.sent();
1047
+ case 13:
1048
+ insertResult = _d.sent();
1007
1049
  assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
1008
- progressTracker = createAssistantProgressTracker(assistantMessageId, initialProgress);
1009
- streamProgress = createAssistantStreamProgressHandler(progressTracker);
1010
- assistantContent = '';
1011
- toolResult = null;
1012
- assistantDebug = null;
1013
- directiveSource = 'none';
1014
- dataQuestion = isAssistantDataQuestion(message);
1015
- lastDirective = null;
1016
- toolResponseDebug = null;
1017
- toolError = null;
1018
- _j.label = 19;
1019
- case 19:
1020
- _j.trys.push([19, 38, 39, 40]);
1021
- return [4 /*yield*/, runCodexInWorkerThread(prompt, runOptions, codexConfig, streamProgress)];
1022
- case 20:
1023
- responseText = _j.sent();
1024
- directive = extractAssistantMongoDirective(responseText);
1025
- directiveSourceText = responseText;
1026
- if (directive) {
1027
- directiveSource = 'model';
1028
- lastDirective = directive;
1029
- }
1030
- if (!(!directive && dataQuestion)) return [3 /*break*/, 24];
1031
- directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1032
- _j.label = 21;
1033
- case 21:
1034
- _j.trys.push([21, 23, , 24]);
1035
- return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1036
- case 22:
1037
- directiveText = _j.sent();
1038
- forcedDirective = extractAssistantMongoDirective(directiveText);
1039
- if (forcedDirective) {
1040
- directive = forcedDirective;
1041
- directiveSourceText = directiveText;
1042
- directiveSource = 'forced';
1043
- lastDirective = forcedDirective;
1044
- }
1045
- return [3 /*break*/, 24];
1046
- case 23:
1047
- _c = _j.sent();
1048
- return [3 /*break*/, 24];
1049
- case 24:
1050
- cleanedResponseText = (directive === null || directive === void 0 ? void 0 : directive.cleaned) || directiveSourceText;
1051
- assistantContent = sanitizeAssistantResponse(cleanedResponseText);
1052
- if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 36];
1053
- toolRequest = buildAssistantToolRequest(directive, input);
1054
- progressTracker.push('Looking up Data');
1055
- _j.label = 25;
1056
- case 25:
1057
- _j.trys.push([25, 34, , 35]);
1058
- if (!(directive.type === 'aggregate')) return [3 /*break*/, 27];
1059
- return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
1060
- case 26:
1061
- _d = _j.sent();
1062
- return [3 /*break*/, 29];
1063
- case 27: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
1064
- case 28:
1065
- _d = _j.sent();
1066
- _j.label = 29;
1067
- case 29:
1068
- toolResponse = _d;
1069
- toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
1070
- ? toolResponse.debug
1071
- : null;
1072
- toolPayload = buildAssistantToolResultPayload(directive, toolResponse);
1073
- toolResult = toolPayload.result;
1074
- progressTracker.push('Drafting response');
1075
- followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
1076
- _j.label = 30;
1077
- case 30:
1078
- _j.trys.push([30, 32, , 33]);
1079
- return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
1080
- case 31:
1081
- followupText = _j.sent();
1082
- assistantContent = sanitizeAssistantResponse(followupText);
1083
- return [3 /*break*/, 33];
1084
- case 32:
1085
- _e = _j.sent();
1086
- assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
1087
- return [3 /*break*/, 33];
1088
- case 33: return [3 /*break*/, 35];
1089
- case 34:
1090
- error_1 = _j.sent();
1091
- assistantContent = buildAssistantToolErrorMessage(error_1, directive, toolRequest);
1092
- toolError = error_1;
1093
- return [3 /*break*/, 35];
1094
- case 35: return [3 /*break*/, 37];
1095
- case 36:
1096
- progressTracker.push('Drafting response');
1097
- _j.label = 37;
1098
- case 37: return [3 /*break*/, 40];
1099
- case 38:
1100
- error_2 = _j.sent();
1101
- assistantContent = buildAssistantCodexErrorMessage(error_2);
1102
- return [3 /*break*/, 40];
1103
- case 39:
1104
- progressTracker.stop();
1105
- return [7 /*endfinally*/];
1106
- case 40:
1107
- if (!assistantContent) {
1108
- assistantContent = buildAssistantCodexErrorMessage(null);
1109
- }
1110
- finalNow = new Date();
1111
- if (isSuperAdmin) {
1112
- assistantDebug = buildAssistantDebugPayload({
1113
- dataQuestion: dataQuestion,
1114
- directive: lastDirective,
1115
- directiveSource: directiveSource,
1116
- toolResult: toolResult,
1117
- toolResponseDebug: toolResponseDebug,
1118
- toolError: toolError
1119
- });
1120
- }
1121
- finalMetadata = __assign(__assign(__assign({ model: resolveCodexModel() }, (requestId ? { request_id: requestId } : {})), (toolResult ? { tool_result: toolResult } : {})), (assistantDebug ? { debug: assistantDebug } : {}));
1122
- finalAssistantDoc = __assign(__assign({}, assistantDoc), { _id: assistantMessageId, content: assistantContent, metadata: finalMetadata, updatedAt: finalNow });
1123
- if (!assistantMessageId) return [3 /*break*/, 42];
1124
- return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: assistantMessageId }, {
1125
- $set: {
1126
- content: assistantContent,
1127
- metadata: finalMetadata,
1128
- updatedAt: finalNow
1050
+ enqueueAssistantCodexRun(function () { return __awaiter(_this, void 0, void 0, function () {
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) {
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
+ };
1066
+ progressTracker = createAssistantProgressTracker(assistantMessageId, initialProgress);
1067
+ streamProgress = createAssistantStreamProgressHandler(progressTracker);
1068
+ assistantContent = '';
1069
+ toolResult = null;
1070
+ assistantDebug = null;
1071
+ directiveSource = 'none';
1072
+ dataQuestion = isAssistantDataQuestion(message);
1073
+ lastDirective = null;
1074
+ toolResponseDebug = null;
1075
+ toolError = null;
1076
+ termHints = [];
1077
+ collectionHints = [];
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;
1092
+ case 2:
1093
+ _p.trys.push([2, 4, , 5]);
1094
+ dbName = resolveAssistantDatabaseName(undefined, input.mongo);
1095
+ db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
1096
+ return [4 /*yield*/, resolveAssistantCollectionHints(hintText, dbName, db)];
1097
+ case 3:
1098
+ collectionHints = _p.sent();
1099
+ return [3 /*break*/, 5];
1100
+ case 4:
1101
+ _a = _p.sent();
1102
+ collectionHints = [];
1103
+ return [3 /*break*/, 5];
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
+ });
1111
+ assistantContext = buildAssistantContext(input, {
1112
+ isSuperAdmin: isSuperAdmin,
1113
+ hasInvoiceAccess: hasInvoiceAccess,
1114
+ customerId: customerId,
1115
+ collectionHints: collectionHints,
1116
+ termHints: termHints
1117
+ });
1118
+ prompt_1 = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1119
+ return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
1120
+ case 6:
1121
+ workspaceRoot = _p.sent();
1122
+ codexConfig = resolveCodexSettings();
1123
+ runOptions = {
1124
+ timeoutMs: resolveCodexTimeoutMs(),
1125
+ threadOptions: {
1126
+ workingDirectory: workspaceRoot,
1127
+ sandboxMode: 'read-only',
1128
+ skipGitRepoCheck: true,
1129
+ modelReasoningEffort: resolveCodexThoughtLevel(),
1130
+ networkAccessEnabled: false,
1131
+ webSearchMode: 'disabled',
1132
+ webSearchEnabled: false,
1133
+ approvalPolicy: 'never'
1134
+ }
1135
+ };
1136
+ responseText = '';
1137
+ directiveText = '';
1138
+ directive = null;
1139
+ if (!dataQuestion) return [3 /*break*/, 10];
1140
+ recordStep('Directive: determine tool', { type: 'data-question' });
1141
+ directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1142
+ _p.label = 7;
1143
+ case 7:
1144
+ _p.trys.push([7, 9, , 10]);
1145
+ return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1146
+ case 8:
1147
+ directiveText = _p.sent();
1148
+ forcedDirective = extractAssistantMongoDirective(directiveText);
1149
+ if (forcedDirective) {
1150
+ directive = forcedDirective;
1151
+ directiveSource = 'model';
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
+ });
1159
+ }
1160
+ return [3 /*break*/, 10];
1161
+ case 9:
1162
+ _b = _p.sent();
1163
+ return [3 /*break*/, 10];
1164
+ case 10:
1165
+ if (!!directive) return [3 /*break*/, 12];
1166
+ recordStep('Response: draft initial answer', { mode: 'full' });
1167
+ return [4 /*yield*/, runCodexInWorkerThread(prompt_1, runOptions, codexConfig, streamProgress)];
1168
+ case 11:
1169
+ responseText = _p.sent();
1170
+ directive = extractAssistantMongoDirective(responseText);
1171
+ if (directive) {
1172
+ directiveSource = 'model';
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
+ });
1180
+ }
1181
+ _p.label = 12;
1182
+ case 12:
1183
+ if (!(!directive && dataQuestion)) return [3 /*break*/, 16];
1184
+ recordStep('Directive: forced retry', { mode: 'directive-only' });
1185
+ directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1186
+ _p.label = 13;
1187
+ case 13:
1188
+ _p.trys.push([13, 15, , 16]);
1189
+ return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1190
+ case 14:
1191
+ directiveText = _p.sent();
1192
+ forcedDirective = extractAssistantMongoDirective(directiveText);
1193
+ if (forcedDirective) {
1194
+ directive = forcedDirective;
1195
+ directiveSource = 'forced';
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
+ });
1203
+ }
1204
+ return [3 /*break*/, 16];
1205
+ case 15:
1206
+ _c = _p.sent();
1207
+ return [3 /*break*/, 16];
1208
+ case 16:
1209
+ cleanedResponseText = (directive === null || directive === void 0 ? void 0 : directive.cleaned) || responseText;
1210
+ if (cleanedResponseText) {
1211
+ assistantContent = sanitizeAssistantResponse(cleanedResponseText);
1212
+ }
1213
+ if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 28];
1214
+ toolRequest = buildAssistantToolRequest(directive, input);
1215
+ progressTracker.push('Grabbing Data');
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;
1222
+ case 17:
1223
+ _p.trys.push([17, 26, , 27]);
1224
+ if (!(directive.type === 'aggregate')) return [3 /*break*/, 19];
1225
+ return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
1226
+ case 18:
1227
+ _d = _p.sent();
1228
+ return [3 /*break*/, 21];
1229
+ case 19: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
1230
+ case 20:
1231
+ _d = _p.sent();
1232
+ _p.label = 21;
1233
+ case 21:
1234
+ toolResponse = _d;
1235
+ toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
1236
+ ? toolResponse.debug
1237
+ : null;
1238
+ toolPayload = buildAssistantToolResultPayload(directive, toolResponse);
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
+ });
1245
+ progressTracker.push('Drafting response');
1246
+ recordStep('Drafting response');
1247
+ followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
1248
+ _p.label = 22;
1249
+ case 22:
1250
+ _p.trys.push([22, 24, , 25]);
1251
+ return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
1252
+ case 23:
1253
+ followupText = _p.sent();
1254
+ assistantContent = sanitizeAssistantResponse(followupText);
1255
+ return [3 /*break*/, 25];
1256
+ case 24:
1257
+ _e = _p.sent();
1258
+ assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
1259
+ return [3 /*break*/, 25];
1260
+ case 25: return [3 /*break*/, 27];
1261
+ case 26:
1262
+ error_2 = _p.sent();
1263
+ assistantContent = buildAssistantToolErrorMessage(error_2, directive, toolRequest);
1264
+ toolError = error_2;
1265
+ return [3 /*break*/, 27];
1266
+ case 27: return [3 /*break*/, 29];
1267
+ case 28:
1268
+ progressTracker.push('Drafting response');
1269
+ recordStep('Drafting response');
1270
+ _p.label = 29;
1271
+ case 29: return [3 /*break*/, 32];
1272
+ case 30:
1273
+ error_3 = _p.sent();
1274
+ assistantContent = buildAssistantCodexErrorMessage(error_3);
1275
+ recordStep('Error', { message: normalizeOptionalString(error_3 === null || error_3 === void 0 ? void 0 : error_3.message) || 'Unknown error' });
1276
+ return [3 /*break*/, 32];
1277
+ case 31:
1278
+ progressTracker.stop();
1279
+ return [7 /*endfinally*/];
1280
+ case 32:
1281
+ if (!assistantContent) {
1282
+ assistantContent = buildAssistantCodexErrorMessage(null);
1283
+ }
1284
+ finalNow = new Date();
1285
+ if (isSuperAdmin) {
1286
+ finishedAt = Date.now();
1287
+ assistantDebug = buildAssistantDebugPayload({
1288
+ dataQuestion: dataQuestion,
1289
+ directive: lastDirective,
1290
+ directiveSource: directiveSource,
1291
+ toolResult: toolResult,
1292
+ toolResponseDebug: toolResponseDebug,
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
+ }
1308
+ });
1309
+ }
1310
+ finalMetadata = __assign(__assign(__assign({ model: resolveCodexModel() }, (requestId ? { request_id: requestId } : {})), (toolResult ? { tool_result: toolResult } : {})), (assistantDebug ? { debug: assistantDebug } : {}));
1311
+ finalAssistantDoc = __assign(__assign({}, assistantDoc), { _id: assistantMessageId, content: assistantContent, metadata: finalMetadata, updatedAt: finalNow });
1312
+ if (!assistantMessageId) return [3 /*break*/, 34];
1313
+ return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: assistantMessageId }, {
1314
+ $set: {
1315
+ content: assistantContent,
1316
+ metadata: finalMetadata,
1317
+ updatedAt: finalNow
1318
+ }
1319
+ })];
1320
+ case 33:
1321
+ _p.sent();
1322
+ _p.label = 34;
1323
+ case 34: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
1324
+ case 35:
1325
+ _p.sent();
1326
+ if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 37];
1327
+ return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
1328
+ case 36:
1329
+ _p.sent();
1330
+ _p.label = 37;
1331
+ case 37: return [2 /*return*/, finalAssistantDoc];
1129
1332
  }
1130
- })];
1131
- case 41:
1132
- _j.sent();
1133
- _j.label = 42;
1134
- case 42: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
1135
- case 43:
1136
- _j.sent();
1137
- if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 45];
1138
- return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
1139
- case 44:
1140
- _j.sent();
1141
- _j.label = 45;
1142
- case 45: return [2 /*return*/, __assign({ conversation: conversation, message: finalAssistantDoc }, (toolResult ? { tool_result: toolResult } : {}))];
1333
+ });
1334
+ }); });
1335
+ return [2 /*return*/, {
1336
+ conversation: conversation
1337
+ }];
1143
1338
  }
1144
1339
  });
1145
1340
  });
1146
1341
  }
1147
1342
  function executeAiAssistantMongoRead(payload, context) {
1148
1343
  return __awaiter(this, void 0, void 0, function () {
1149
- 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;
1150
1345
  var _c, _d;
1151
1346
  return __generator(this, function (_e) {
1152
1347
  switch (_e.label) {
@@ -1227,14 +1422,25 @@ function executeAiAssistantMongoRead(payload, context) {
1227
1422
  ? documents
1228
1423
  : documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
1229
1424
  includeIds = ((_d = input.options) === null || _d === void 0 ? void 0 : _d.includeIds) === true;
1230
- 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, {
1231
1433
  includeIds: includeIds,
1232
1434
  maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
1233
- maxRows: normalized.findOptions.limit
1435
+ maxRows: normalized.findOptions.limit,
1436
+ priorityFields: priorityFields
1234
1437
  });
1235
1438
  if (total !== null) {
1236
1439
  display.total = total;
1237
1440
  }
1441
+ if (Object.keys(fieldAliases).length) {
1442
+ fallbackMeta.fieldAliases = fieldAliases;
1443
+ }
1238
1444
  return [2 /*return*/, __assign({ documents: sanitizedDocuments, total: total, display: display }, (isSuperAdmin ? {
1239
1445
  debug: {
1240
1446
  collection: collection,
@@ -1623,7 +1829,7 @@ function buildAssistantDebugPayload(params) {
1623
1829
  notes.push("Tool error: ".concat(errorMessage));
1624
1830
  }
1625
1831
  }
1626
- return {
1832
+ var payload = {
1627
1833
  decision: {
1628
1834
  dataQuestion: params.dataQuestion,
1629
1835
  directiveSource: params.directiveSource
@@ -1647,6 +1853,10 @@ function buildAssistantDebugPayload(params) {
1647
1853
  fallbacks: ((_t = params.toolResponseDebug) === null || _t === void 0 ? void 0 : _t.fallbacks) || undefined,
1648
1854
  notes: notes
1649
1855
  };
1856
+ if (params.trace && typeof params.trace === 'object') {
1857
+ payload.trace = params.trace;
1858
+ }
1859
+ return payload;
1650
1860
  }
1651
1861
  function buildAssistantToolErrorMessage(error, directive, request) {
1652
1862
  var _a, _b;
@@ -1684,7 +1894,7 @@ function deriveAssistantStreamStatus(event) {
1684
1894
  return null;
1685
1895
  }
1686
1896
  if (event.type === 'thread.started' || event.type === 'turn.started') {
1687
- return 'Reviewing request';
1897
+ return 'Planning';
1688
1898
  }
1689
1899
  if (event.type === 'turn.completed') {
1690
1900
  return 'Drafting response';
@@ -1695,13 +1905,13 @@ function deriveAssistantStreamStatus(event) {
1695
1905
  return null;
1696
1906
  }
1697
1907
  if (itemType === 'mcp_tool_call') {
1698
- return 'Calling tool';
1908
+ return 'Grabbing Data';
1699
1909
  }
1700
1910
  if (itemType === 'command_execution') {
1701
- return 'Running command';
1911
+ return 'Grabbing Data';
1702
1912
  }
1703
1913
  if (itemType === 'web_search') {
1704
- return 'Searching references';
1914
+ return 'Planning';
1705
1915
  }
1706
1916
  if (itemType === 'file_change') {
1707
1917
  return 'Drafting response';
@@ -1710,7 +1920,7 @@ function deriveAssistantStreamStatus(event) {
1710
1920
  return 'Drafting response';
1711
1921
  }
1712
1922
  if (itemType === 'reasoning') {
1713
- return 'Analyzing';
1923
+ return 'Planning';
1714
1924
  }
1715
1925
  }
1716
1926
  return null;
@@ -1896,6 +2106,219 @@ function normalizeColumnPriorityKey(column) {
1896
2106
  var base = trimmed.includes('.') ? trimmed.split('.').pop() || trimmed : trimmed;
1897
2107
  return base.toLowerCase();
1898
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
+ }
1899
2322
  function formatDisplayColumnName(column) {
1900
2323
  var trimmed = String(column || '').trim();
1901
2324
  if (!trimmed) {
@@ -1914,7 +2337,22 @@ function formatDisplayColumnName(column) {
1914
2337
  if (normalized === 'updatedat') {
1915
2338
  return 'Updated At';
1916
2339
  }
1917
- 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(); });
1918
2356
  }
1919
2357
  function truncateDisplayText(value, maxLength) {
1920
2358
  if (maxLength === void 0) { maxLength = AI_ASSISTANT_DISPLAY_STRING_LIMIT; }
@@ -2410,7 +2848,7 @@ function matchContainsField(value, field) {
2410
2848
  });
2411
2849
  }
2412
2850
  function resolveAggregateCompletionFallback(pipeline) {
2413
- var e_1, _a;
2851
+ var e_3, _a;
2414
2852
  if (!Array.isArray(pipeline)) {
2415
2853
  return null;
2416
2854
  }
@@ -2423,7 +2861,7 @@ function resolveAggregateCompletionFallback(pipeline) {
2423
2861
  }
2424
2862
  var addFields = stage.$addFields;
2425
2863
  try {
2426
- 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()) {
2427
2865
  var key = _c.value;
2428
2866
  if (!isCompletionFieldName(key)) {
2429
2867
  continue;
@@ -2437,12 +2875,12 @@ function resolveAggregateCompletionFallback(pipeline) {
2437
2875
  }
2438
2876
  }
2439
2877
  }
2440
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
2878
+ catch (e_3_1) { e_3 = { error: e_3_1 }; }
2441
2879
  finally {
2442
2880
  try {
2443
2881
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
2444
2882
  }
2445
- finally { if (e_1) throw e_1.error; }
2883
+ finally { if (e_3) throw e_3.error; }
2446
2884
  }
2447
2885
  if (candidateField) {
2448
2886
  break;
@@ -2809,6 +3247,27 @@ function tokenizeCollectionText(value) {
2809
3247
  });
2810
3248
  return Array.from(new Set(tokens));
2811
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
+ }
2812
3271
  function listAssistantCollections(db, dbName) {
2813
3272
  return __awaiter(this, void 0, void 0, function () {
2814
3273
  var cacheKey, cached, now, collections, names, _a;
@@ -2940,7 +3399,7 @@ function resolveAssistantCollectionHints(message, dbName, db) {
2940
3399
  });
2941
3400
  }
2942
3401
  function findQueryDateField(query) {
2943
- var e_2, _a, e_3, _b;
3402
+ var e_4, _a, e_5, _b;
2944
3403
  if (!query || typeof query !== 'object') {
2945
3404
  return null;
2946
3405
  }
@@ -2954,12 +3413,12 @@ function findQueryDateField(query) {
2954
3413
  }
2955
3414
  }
2956
3415
  }
2957
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
3416
+ catch (e_4_1) { e_4 = { error: e_4_1 }; }
2958
3417
  finally {
2959
3418
  try {
2960
3419
  if (query_1_1 && !query_1_1.done && (_a = query_1.return)) _a.call(query_1);
2961
3420
  }
2962
- finally { if (e_2) throw e_2.error; }
3421
+ finally { if (e_4) throw e_4.error; }
2963
3422
  }
2964
3423
  return null;
2965
3424
  }
@@ -2978,12 +3437,12 @@ function findQueryDateField(query) {
2978
3437
  }
2979
3438
  }
2980
3439
  }
2981
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
3440
+ catch (e_5_1) { e_5 = { error: e_5_1 }; }
2982
3441
  finally {
2983
3442
  try {
2984
3443
  if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
2985
3444
  }
2986
- finally { if (e_3) throw e_3.error; }
3445
+ finally { if (e_5) throw e_5.error; }
2987
3446
  }
2988
3447
  return null;
2989
3448
  }
@@ -3013,7 +3472,7 @@ function resolveQueryDateFieldFallback(query) {
3013
3472
  return { from: dateField, to: fallback };
3014
3473
  }
3015
3474
  function containsForbiddenMongoOperators(value) {
3016
- var e_4, _a;
3475
+ var e_6, _a;
3017
3476
  if (!value || typeof value !== 'object') {
3018
3477
  return false;
3019
3478
  }
@@ -3032,12 +3491,12 @@ function containsForbiddenMongoOperators(value) {
3032
3491
  }
3033
3492
  }
3034
3493
  }
3035
- catch (e_4_1) { e_4 = { error: e_4_1 }; }
3494
+ catch (e_6_1) { e_6 = { error: e_6_1 }; }
3036
3495
  finally {
3037
3496
  try {
3038
3497
  if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
3039
3498
  }
3040
- finally { if (e_4) throw e_4.error; }
3499
+ finally { if (e_6) throw e_6.error; }
3041
3500
  }
3042
3501
  return false;
3043
3502
  }
@@ -3271,8 +3730,8 @@ function applyCodexStreamStatusHandler(runOptions, streamStatusHandler) {
3271
3730
  }
3272
3731
  function waitForCodexWorkerMessage(worker, streamStatusHandler) {
3273
3732
  return __awaiter(this, void 0, void 0, function () {
3274
- var _a, _b, _c, _d, message, payload, status_1, e_5_1;
3275
- 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;
3276
3735
  return __generator(this, function (_h) {
3277
3736
  switch (_h.label) {
3278
3737
  case 0:
@@ -3299,8 +3758,8 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
3299
3758
  return [3 /*break*/, 1];
3300
3759
  case 4: return [3 /*break*/, 11];
3301
3760
  case 5:
3302
- e_5_1 = _h.sent();
3303
- e_5 = { error: e_5_1 };
3761
+ e_7_1 = _h.sent();
3762
+ e_7 = { error: e_7_1 };
3304
3763
  return [3 /*break*/, 11];
3305
3764
  case 6:
3306
3765
  _h.trys.push([6, , 9, 10]);
@@ -3311,7 +3770,7 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
3311
3770
  _h.label = 8;
3312
3771
  case 8: return [3 /*break*/, 10];
3313
3772
  case 9:
3314
- if (e_5) throw e_5.error;
3773
+ if (e_7) throw e_7.error;
3315
3774
  return [7 /*endfinally*/];
3316
3775
  case 10: return [7 /*endfinally*/];
3317
3776
  case 11: throw new CodexWorkerBootstrapError('Codex worker exited before completing.');
@@ -3321,7 +3780,7 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
3321
3780
  }
3322
3781
  function runCodexInWorkerThread(prompt, runOptions, config, streamStatusHandler) {
3323
3782
  return __awaiter(this, void 0, void 0, function () {
3324
- var streamedOptions, codexClient, workerPath, codexClient, error_3, codexClient;
3783
+ var streamedOptions, codexClient, workerPath, codexClient, error_4, codexClient;
3325
3784
  return __generator(this, function (_a) {
3326
3785
  switch (_a.label) {
3327
3786
  case 0:
@@ -3342,11 +3801,11 @@ function runCodexInWorkerThread(prompt, runOptions, config, streamStatusHandler)
3342
3801
  return [4 /*yield*/, runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config, streamStatusHandler)];
3343
3802
  case 6: return [2 /*return*/, _a.sent()];
3344
3803
  case 7:
3345
- error_3 = _a.sent();
3346
- if (!(error_3 instanceof CodexWorkerBootstrapError)) {
3347
- throw error_3;
3804
+ error_4 = _a.sent();
3805
+ if (!(error_4 instanceof CodexWorkerBootstrapError)) {
3806
+ throw error_4;
3348
3807
  }
3349
- console.error('Codex worker bootstrap failed, falling back to in-process run.', error_3);
3808
+ console.error('Codex worker bootstrap failed, falling back to in-process run.', error_4);
3350
3809
  codexClient = getAssistantCodexClient();
3351
3810
  return [4 /*yield*/, codexClient.run(prompt, streamedOptions)];
3352
3811
  case 8: return [2 /*return*/, _a.sent()];
@@ -3384,7 +3843,7 @@ function runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config,
3384
3843
  timeoutMs = ((sanitizedOptions === null || sanitizedOptions === void 0 ? void 0 : sanitizedOptions.timeoutMs) || resolveCodexTimeoutMs()) + 15000;
3385
3844
  timeoutController = new AbortController();
3386
3845
  timeoutPromise = (function () { return __awaiter(_this, void 0, void 0, function () {
3387
- var error_4;
3846
+ var error_5;
3388
3847
  return __generator(this, function (_a) {
3389
3848
  switch (_a.label) {
3390
3849
  case 0:
@@ -3394,11 +3853,11 @@ function runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config,
3394
3853
  _a.sent();
3395
3854
  return [2 /*return*/, { type: 'timeout' }];
3396
3855
  case 2:
3397
- error_4 = _a.sent();
3398
- if ((error_4 === null || error_4 === void 0 ? void 0 : error_4.name) === 'AbortError') {
3856
+ error_5 = _a.sent();
3857
+ if ((error_5 === null || error_5 === void 0 ? void 0 : error_5.name) === 'AbortError') {
3399
3858
  return [2 /*return*/, { type: 'aborted' }];
3400
3859
  }
3401
- throw error_4;
3860
+ throw error_5;
3402
3861
  case 3: return [2 /*return*/];
3403
3862
  }
3404
3863
  });
@@ -3663,6 +4122,12 @@ function buildAssistantContext(input, userContext) {
3663
4122
  if (collectionHints.length) {
3664
4123
  lines.push("Collection hints: ".concat(collectionHints.join(', ')));
3665
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
+ }
3666
4131
  var mongoDb = normalizeOptionalString((_c = input === null || input === void 0 ? void 0 : input.mongo) === null || _c === void 0 ? void 0 : _c.database);
3667
4132
  var mongoDbs = Array.isArray((_d = input === null || input === void 0 ? void 0 : input.mongo) === null || _d === void 0 ? void 0 : _d.databases)
3668
4133
  ? input.mongo.databases.map(function (value) { return normalizeOptionalString(value); }).filter(Boolean)
@@ -3693,7 +4158,7 @@ function normalizeRouteMatchKey(value) {
3693
4158
  return normalizeRouteKey(value).toLowerCase();
3694
4159
  }
3695
4160
  function buildClientRouteIndex() {
3696
- var e_6, _a;
4161
+ var e_8, _a;
3697
4162
  var _b;
3698
4163
  var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
3699
4164
  var set = new Set();
@@ -3712,12 +4177,12 @@ function buildClientRouteIndex() {
3712
4177
  }
3713
4178
  }
3714
4179
  }
3715
- catch (e_6_1) { e_6 = { error: e_6_1 }; }
4180
+ catch (e_8_1) { e_8 = { error: e_8_1 }; }
3716
4181
  finally {
3717
4182
  try {
3718
4183
  if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
3719
4184
  }
3720
- finally { if (e_6) throw e_6.error; }
4185
+ finally { if (e_8) throw e_8.error; }
3721
4186
  }
3722
4187
  return { set: set, map: map, size: routes.length };
3723
4188
  }
@@ -3843,7 +4308,7 @@ function sanitizeAssistantResponse(value) {
3843
4308
  return normalizeAssistantRoutes(normalizedCurrency);
3844
4309
  }
3845
4310
  function evaluateAssistantGuardrails(message) {
3846
- var e_7, _a;
4311
+ var e_9, _a;
3847
4312
  var normalized = String(message || '').toLowerCase();
3848
4313
  var patterns = [
3849
4314
  {
@@ -3889,12 +4354,12 @@ function evaluateAssistantGuardrails(message) {
3889
4354
  }
3890
4355
  }
3891
4356
  }
3892
- catch (e_7_1) { e_7 = { error: e_7_1 }; }
4357
+ catch (e_9_1) { e_9 = { error: e_9_1 }; }
3893
4358
  finally {
3894
4359
  try {
3895
4360
  if (patterns_1_1 && !patterns_1_1.done && (_a = patterns_1.return)) _a.call(patterns_1);
3896
4361
  }
3897
- finally { if (e_7) throw e_7.error; }
4362
+ finally { if (e_9) throw e_9.error; }
3898
4363
  }
3899
4364
  return null;
3900
4365
  }
@@ -4058,8 +4523,8 @@ function handleCodexUpload(id_conversation, file_name, content_base64, size, con
4058
4523
  }
4059
4524
  function readAttachmentContents(attachments) {
4060
4525
  return __awaiter(this, void 0, void 0, function () {
4061
- 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;
4062
- 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;
4063
4528
  return __generator(this, function (_c) {
4064
4529
  switch (_c.label) {
4065
4530
  case 0:
@@ -4138,14 +4603,14 @@ function readAttachmentContents(attachments) {
4138
4603
  return [3 /*break*/, 2];
4139
4604
  case 10: return [3 /*break*/, 13];
4140
4605
  case 11:
4141
- e_8_1 = _c.sent();
4142
- e_8 = { error: e_8_1 };
4606
+ e_10_1 = _c.sent();
4607
+ e_10 = { error: e_10_1 };
4143
4608
  return [3 /*break*/, 13];
4144
4609
  case 12:
4145
4610
  try {
4146
4611
  if (attachments_1_1 && !attachments_1_1.done && (_b = attachments_1.return)) _b.call(attachments_1);
4147
4612
  }
4148
- finally { if (e_8) throw e_8.error; }
4613
+ finally { if (e_10) throw e_10.error; }
4149
4614
  return [7 /*endfinally*/];
4150
4615
  case 13: return [2 /*return*/, {
4151
4616
  promptText: chunks.length ? "\n\nAttachments:\n".concat(chunks.join('\n\n')) : '',
@@ -4322,7 +4787,7 @@ function estimateUsage(messages, responseText, model) {
4322
4787
  };
4323
4788
  }
4324
4789
  function evaluateGuardrails(message) {
4325
- var e_9, _a;
4790
+ var e_11, _a;
4326
4791
  var normalized = String(message || '').toLowerCase();
4327
4792
  var patterns = [
4328
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.' },
@@ -4344,12 +4809,12 @@ function evaluateGuardrails(message) {
4344
4809
  }
4345
4810
  }
4346
4811
  }
4347
- catch (e_9_1) { e_9 = { error: e_9_1 }; }
4812
+ catch (e_11_1) { e_11 = { error: e_11_1 }; }
4348
4813
  finally {
4349
4814
  try {
4350
4815
  if (patterns_2_1 && !patterns_2_1.done && (_a = patterns_2.return)) _a.call(patterns_2);
4351
4816
  }
4352
- finally { if (e_9) throw e_9.error; }
4817
+ finally { if (e_11) throw e_11.error; }
4353
4818
  }
4354
4819
  return null;
4355
4820
  }