@resolveio/server-lib 20.15.5 → 20.15.6

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 = [
@@ -256,6 +257,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
256
257
  '- Do not assist with hacking, bypassing security, or abuse.',
257
258
  'Accuracy & tools:',
258
259
  '- 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
+ '- 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
261
  '- Map user wording to internal collections/fields yourself. Do not ask for property names unless required to run a query.',
260
262
  '- 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
263
  '- Prefer running a small Mongo read over asking multiple questions.',
@@ -264,7 +266,9 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
264
266
  '- 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
267
  '- 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
268
  '- Use the codebase context to choose correct collections/fields/workflows and use MONGO_READ/MONGO_AGG to answer with real data when needed.',
269
+ '- 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
270
  '- Assume a relevant collection exists; if verification reads return zero data, report no data found instead of interrogating the user.',
271
+ '- 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
272
  '- For direct questions, answer first. Ask a single follow-up only if required to proceed.',
269
273
  'Data Presentation:',
270
274
  '- Output plain Markdown (NO triple backticks).',
@@ -308,6 +312,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
308
312
  '- Only request data when the user has permission for that module; invoice data requires invoice view access.',
309
313
  '- If the user lacks permission, answer without data and explain how to view it in the app or request access.',
310
314
  '- For simple counts or time-range totals, use MONGO_READ (includeTotal). For breakdowns, rankings, or sums grouped by a field, use MONGO_AGG.',
315
+ '- For performance, keep pipelines minimal: avoid $push arrays or large fields unless the user explicitly asks for them.',
311
316
  '- 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
317
  '- 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
318
  '- For creation-date questions when both date_created and createdAt exist, match both with $or so results are not missed.',
@@ -327,6 +332,76 @@ var AI_FORM_PATCH_SYSTEM_PROMPT = [
327
332
  '- Use medium reasoning effort.'
328
333
  ].join('\n');
329
334
  var assistantCodexClient = null;
335
+ var assistantCodexRunQueue = [];
336
+ var assistantCodexRunDraining = false;
337
+ /* eslint-enable no-unused-vars */
338
+ function enqueueAssistantCodexRun(task) {
339
+ var _this = this;
340
+ assistantCodexRunQueue.push(task);
341
+ if (assistantCodexRunDraining) {
342
+ return;
343
+ }
344
+ assistantCodexRunDraining = true;
345
+ queueMicrotask(function () { return __awaiter(_this, void 0, void 0, function () {
346
+ return __generator(this, function (_a) {
347
+ switch (_a.label) {
348
+ case 0: return [4 /*yield*/, drainAssistantCodexRunQueue()];
349
+ case 1:
350
+ _a.sent();
351
+ return [2 /*return*/];
352
+ }
353
+ });
354
+ }); });
355
+ }
356
+ function drainAssistantCodexRunQueue() {
357
+ return __awaiter(this, void 0, void 0, function () {
358
+ var next, error_1;
359
+ var _this = this;
360
+ return __generator(this, function (_a) {
361
+ switch (_a.label) {
362
+ case 0:
363
+ _a.trys.push([0, , 7, 8]);
364
+ _a.label = 1;
365
+ case 1:
366
+ if (!assistantCodexRunQueue.length) return [3 /*break*/, 6];
367
+ next = assistantCodexRunQueue.shift();
368
+ if (!next) {
369
+ return [3 /*break*/, 1];
370
+ }
371
+ _a.label = 2;
372
+ case 2:
373
+ _a.trys.push([2, 4, , 5]);
374
+ return [4 /*yield*/, next()];
375
+ case 3:
376
+ _a.sent();
377
+ return [3 /*break*/, 5];
378
+ case 4:
379
+ error_1 = _a.sent();
380
+ console.error(new Date(), 'AI assistant run failed:', error_1);
381
+ return [3 /*break*/, 5];
382
+ case 5: return [3 /*break*/, 1];
383
+ case 6: return [3 /*break*/, 8];
384
+ case 7:
385
+ assistantCodexRunDraining = false;
386
+ if (assistantCodexRunQueue.length) {
387
+ assistantCodexRunDraining = true;
388
+ queueMicrotask(function () { return __awaiter(_this, void 0, void 0, function () {
389
+ return __generator(this, function (_a) {
390
+ switch (_a.label) {
391
+ case 0: return [4 /*yield*/, drainAssistantCodexRunQueue()];
392
+ case 1:
393
+ _a.sent();
394
+ return [2 /*return*/];
395
+ }
396
+ });
397
+ }); });
398
+ }
399
+ return [7 /*endfinally*/];
400
+ case 8: return [2 /*return*/];
401
+ }
402
+ });
403
+ });
404
+ }
330
405
  function loadAiTerminalMethods(methodManager) {
331
406
  methodManager.methods({
332
407
  aiTerminalConversationCreate: {
@@ -854,10 +929,11 @@ function executeAiFormPatch(payload, context) {
854
929
  }
855
930
  function executeAiAssistantCodexRun(payload, context) {
856
931
  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) {
932
+ 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;
933
+ var _this = this;
934
+ var _b, _c;
935
+ return __generator(this, function (_d) {
936
+ switch (_d.label) {
861
937
  case 0:
862
938
  input = payload || {};
863
939
  message = normalizeOptionalString(input.message);
@@ -872,7 +948,7 @@ function executeAiAssistantCodexRun(payload, context) {
872
948
  if (!(guardrail === null || guardrail === void 0 ? void 0 : guardrail.blocked)) return [3 /*break*/, 5];
873
949
  return [4 /*yield*/, ensureConversation(input, 'codex')];
874
950
  case 1:
875
- conversation_2 = _j.sent();
951
+ conversation_2 = _d.sent();
876
952
  now_2 = new Date();
877
953
  userMsg = {
878
954
  id_conversation: conversation_2._id,
@@ -892,13 +968,13 @@ function executeAiAssistantCodexRun(payload, context) {
892
968
  };
893
969
  return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userMsg)];
894
970
  case 2:
895
- _j.sent();
971
+ _d.sent();
896
972
  return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(assistantMsg)];
897
973
  case 3:
898
- _j.sent();
974
+ _d.sent();
899
975
  return [4 /*yield*/, touchConversation(conversation_2._id, now_2)];
900
976
  case 4:
901
- _j.sent();
977
+ _d.sent();
902
978
  return [2 /*return*/, {
903
979
  conversation: conversation_2,
904
980
  message: assistantMsg,
@@ -906,27 +982,27 @@ function executeAiAssistantCodexRun(payload, context) {
906
982
  }];
907
983
  case 5: return [4 /*yield*/, user_collection_1.Users.findById(context === null || context === void 0 ? void 0 : context.id_user)];
908
984
  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);
985
+ user = _d.sent();
986
+ isSuperAdmin = !!((_b = user === null || user === void 0 ? void 0 : user.roles) === null || _b === void 0 ? void 0 : _b.super_admin);
911
987
  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);
988
+ customerId = normalizeOptionalString((_c = user === null || user === void 0 ? void 0 : user.other) === null || _c === void 0 ? void 0 : _c.id_customer);
913
989
  return [4 /*yield*/, ensureConversation(input, 'codex')];
914
990
  case 7:
915
- conversation = _j.sent();
991
+ conversation = _d.sent();
916
992
  now = new Date();
917
993
  attachments = Array.isArray(input.attachments) ? input.attachments : [];
918
994
  return [4 /*yield*/, readAttachmentContents(attachments)];
919
995
  case 8:
920
- attachmentData = _j.sent();
996
+ attachmentData = _d.sent();
921
997
  historyLimit = normalizeHistoryLimit(input.max_history);
922
998
  if (!(historyLimit > 0)) return [3 /*break*/, 10];
923
999
  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
1000
  case 9:
925
- _a = _j.sent();
1001
+ _a = _d.sent();
926
1002
  return [3 /*break*/, 11];
927
1003
  case 10:
928
1004
  _a = [];
929
- _j.label = 11;
1005
+ _d.label = 11;
930
1006
  case 11:
931
1007
  history = _a;
932
1008
  historyLines = [];
@@ -937,49 +1013,6 @@ function executeAiAssistantCodexRun(payload, context) {
937
1013
  historyLines.push("".concat(role, ": ").concat(content));
938
1014
  }
939
1015
  });
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
1016
  userDoc = {
984
1017
  id_conversation: conversation._id,
985
1018
  role: 'user',
@@ -989,7 +1022,7 @@ function executeAiAssistantCodexRun(payload, context) {
989
1022
  createdAt: now,
990
1023
  updatedAt: now
991
1024
  };
992
- initialProgress = ['Thinking'];
1025
+ initialProgress = ['Planning'];
993
1026
  assistantDoc = {
994
1027
  id_conversation: conversation._id,
995
1028
  role: 'assistant',
@@ -999,147 +1032,227 @@ function executeAiAssistantCodexRun(payload, context) {
999
1032
  updatedAt: now
1000
1033
  };
1001
1034
  return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userDoc)];
1002
- case 17:
1003
- _j.sent();
1035
+ case 12:
1036
+ _d.sent();
1004
1037
  return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(assistantDoc)];
1005
- case 18:
1006
- insertResult = _j.sent();
1038
+ case 13:
1039
+ insertResult = _d.sent();
1007
1040
  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
1041
+ 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) {
1046
+ case 0:
1047
+ progressTracker = createAssistantProgressTracker(assistantMessageId, initialProgress);
1048
+ streamProgress = createAssistantStreamProgressHandler(progressTracker);
1049
+ assistantContent = '';
1050
+ toolResult = null;
1051
+ assistantDebug = null;
1052
+ directiveSource = 'none';
1053
+ dataQuestion = isAssistantDataQuestion(message);
1054
+ lastDirective = null;
1055
+ toolResponseDebug = null;
1056
+ toolError = null;
1057
+ _g.label = 1;
1058
+ case 1:
1059
+ _g.trys.push([1, 30, 31, 32]);
1060
+ collectionHints = [];
1061
+ _g.label = 2;
1062
+ case 2:
1063
+ _g.trys.push([2, 4, , 5]);
1064
+ dbName = resolveAssistantDatabaseName(undefined, input.mongo);
1065
+ db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
1066
+ hintText = [
1067
+ message,
1068
+ normalizeOptionalString((_f = input === null || input === void 0 ? void 0 : input.context) === null || _f === void 0 ? void 0 : _f.route)
1069
+ ].filter(Boolean).join(' ');
1070
+ return [4 /*yield*/, resolveAssistantCollectionHints(hintText, dbName, db)];
1071
+ case 3:
1072
+ collectionHints = _g.sent();
1073
+ return [3 /*break*/, 5];
1074
+ case 4:
1075
+ _a = _g.sent();
1076
+ collectionHints = [];
1077
+ return [3 /*break*/, 5];
1078
+ case 5:
1079
+ assistantContext = buildAssistantContext(input, {
1080
+ isSuperAdmin: isSuperAdmin,
1081
+ hasInvoiceAccess: hasInvoiceAccess,
1082
+ customerId: customerId,
1083
+ collectionHints: collectionHints
1084
+ });
1085
+ prompt_1 = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1086
+ return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
1087
+ case 6:
1088
+ workspaceRoot = _g.sent();
1089
+ codexConfig = resolveCodexSettings();
1090
+ runOptions = {
1091
+ timeoutMs: resolveCodexTimeoutMs(),
1092
+ threadOptions: {
1093
+ workingDirectory: workspaceRoot,
1094
+ sandboxMode: 'read-only',
1095
+ skipGitRepoCheck: true,
1096
+ modelReasoningEffort: resolveCodexThoughtLevel(),
1097
+ networkAccessEnabled: false,
1098
+ webSearchMode: 'disabled',
1099
+ webSearchEnabled: false,
1100
+ approvalPolicy: 'never'
1101
+ }
1102
+ };
1103
+ responseText = '';
1104
+ directiveText = '';
1105
+ directive = null;
1106
+ if (!dataQuestion) return [3 /*break*/, 10];
1107
+ directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1108
+ _g.label = 7;
1109
+ case 7:
1110
+ _g.trys.push([7, 9, , 10]);
1111
+ return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1112
+ case 8:
1113
+ directiveText = _g.sent();
1114
+ forcedDirective = extractAssistantMongoDirective(directiveText);
1115
+ if (forcedDirective) {
1116
+ directive = forcedDirective;
1117
+ directiveSource = 'model';
1118
+ lastDirective = forcedDirective;
1119
+ }
1120
+ return [3 /*break*/, 10];
1121
+ case 9:
1122
+ _b = _g.sent();
1123
+ return [3 /*break*/, 10];
1124
+ case 10:
1125
+ if (!!directive) return [3 /*break*/, 12];
1126
+ return [4 /*yield*/, runCodexInWorkerThread(prompt_1, runOptions, codexConfig, streamProgress)];
1127
+ case 11:
1128
+ responseText = _g.sent();
1129
+ directive = extractAssistantMongoDirective(responseText);
1130
+ if (directive) {
1131
+ directiveSource = 'model';
1132
+ lastDirective = directive;
1133
+ }
1134
+ _g.label = 12;
1135
+ case 12:
1136
+ if (!(!directive && dataQuestion)) return [3 /*break*/, 16];
1137
+ directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1138
+ _g.label = 13;
1139
+ case 13:
1140
+ _g.trys.push([13, 15, , 16]);
1141
+ return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1142
+ case 14:
1143
+ directiveText = _g.sent();
1144
+ forcedDirective = extractAssistantMongoDirective(directiveText);
1145
+ if (forcedDirective) {
1146
+ directive = forcedDirective;
1147
+ directiveSource = 'forced';
1148
+ lastDirective = forcedDirective;
1149
+ }
1150
+ return [3 /*break*/, 16];
1151
+ case 15:
1152
+ _c = _g.sent();
1153
+ return [3 /*break*/, 16];
1154
+ case 16:
1155
+ cleanedResponseText = (directive === null || directive === void 0 ? void 0 : directive.cleaned) || responseText;
1156
+ if (cleanedResponseText) {
1157
+ assistantContent = sanitizeAssistantResponse(cleanedResponseText);
1158
+ }
1159
+ if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 28];
1160
+ toolRequest = buildAssistantToolRequest(directive, input);
1161
+ progressTracker.push('Grabbing Data');
1162
+ _g.label = 17;
1163
+ case 17:
1164
+ _g.trys.push([17, 26, , 27]);
1165
+ if (!(directive.type === 'aggregate')) return [3 /*break*/, 19];
1166
+ return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
1167
+ case 18:
1168
+ _d = _g.sent();
1169
+ return [3 /*break*/, 21];
1170
+ case 19: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
1171
+ case 20:
1172
+ _d = _g.sent();
1173
+ _g.label = 21;
1174
+ case 21:
1175
+ toolResponse = _d;
1176
+ toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
1177
+ ? toolResponse.debug
1178
+ : null;
1179
+ toolPayload = buildAssistantToolResultPayload(directive, toolResponse);
1180
+ toolResult = toolPayload.result;
1181
+ progressTracker.push('Drafting response');
1182
+ followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
1183
+ _g.label = 22;
1184
+ case 22:
1185
+ _g.trys.push([22, 24, , 25]);
1186
+ return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
1187
+ case 23:
1188
+ followupText = _g.sent();
1189
+ assistantContent = sanitizeAssistantResponse(followupText);
1190
+ return [3 /*break*/, 25];
1191
+ case 24:
1192
+ _e = _g.sent();
1193
+ assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
1194
+ return [3 /*break*/, 25];
1195
+ case 25: return [3 /*break*/, 27];
1196
+ case 26:
1197
+ error_2 = _g.sent();
1198
+ assistantContent = buildAssistantToolErrorMessage(error_2, directive, toolRequest);
1199
+ toolError = error_2;
1200
+ return [3 /*break*/, 27];
1201
+ case 27: return [3 /*break*/, 29];
1202
+ case 28:
1203
+ progressTracker.push('Drafting response');
1204
+ _g.label = 29;
1205
+ case 29: return [3 /*break*/, 32];
1206
+ case 30:
1207
+ error_3 = _g.sent();
1208
+ assistantContent = buildAssistantCodexErrorMessage(error_3);
1209
+ return [3 /*break*/, 32];
1210
+ case 31:
1211
+ progressTracker.stop();
1212
+ return [7 /*endfinally*/];
1213
+ case 32:
1214
+ if (!assistantContent) {
1215
+ assistantContent = buildAssistantCodexErrorMessage(null);
1216
+ }
1217
+ finalNow = new Date();
1218
+ if (isSuperAdmin) {
1219
+ assistantDebug = buildAssistantDebugPayload({
1220
+ dataQuestion: dataQuestion,
1221
+ directive: lastDirective,
1222
+ directiveSource: directiveSource,
1223
+ toolResult: toolResult,
1224
+ toolResponseDebug: toolResponseDebug,
1225
+ toolError: toolError
1226
+ });
1227
+ }
1228
+ finalMetadata = __assign(__assign(__assign({ model: resolveCodexModel() }, (requestId ? { request_id: requestId } : {})), (toolResult ? { tool_result: toolResult } : {})), (assistantDebug ? { debug: assistantDebug } : {}));
1229
+ finalAssistantDoc = __assign(__assign({}, assistantDoc), { _id: assistantMessageId, content: assistantContent, metadata: finalMetadata, updatedAt: finalNow });
1230
+ if (!assistantMessageId) return [3 /*break*/, 34];
1231
+ return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: assistantMessageId }, {
1232
+ $set: {
1233
+ content: assistantContent,
1234
+ metadata: finalMetadata,
1235
+ updatedAt: finalNow
1236
+ }
1237
+ })];
1238
+ case 33:
1239
+ _g.sent();
1240
+ _g.label = 34;
1241
+ case 34: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
1242
+ case 35:
1243
+ _g.sent();
1244
+ if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 37];
1245
+ return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
1246
+ case 36:
1247
+ _g.sent();
1248
+ _g.label = 37;
1249
+ case 37: return [2 /*return*/, finalAssistantDoc];
1129
1250
  }
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 } : {}))];
1251
+ });
1252
+ }); });
1253
+ return [2 /*return*/, {
1254
+ conversation: conversation
1255
+ }];
1143
1256
  }
1144
1257
  });
1145
1258
  });
@@ -1684,7 +1797,7 @@ function deriveAssistantStreamStatus(event) {
1684
1797
  return null;
1685
1798
  }
1686
1799
  if (event.type === 'thread.started' || event.type === 'turn.started') {
1687
- return 'Reviewing request';
1800
+ return 'Planning';
1688
1801
  }
1689
1802
  if (event.type === 'turn.completed') {
1690
1803
  return 'Drafting response';
@@ -1695,13 +1808,13 @@ function deriveAssistantStreamStatus(event) {
1695
1808
  return null;
1696
1809
  }
1697
1810
  if (itemType === 'mcp_tool_call') {
1698
- return 'Calling tool';
1811
+ return 'Grabbing Data';
1699
1812
  }
1700
1813
  if (itemType === 'command_execution') {
1701
- return 'Running command';
1814
+ return 'Grabbing Data';
1702
1815
  }
1703
1816
  if (itemType === 'web_search') {
1704
- return 'Searching references';
1817
+ return 'Planning';
1705
1818
  }
1706
1819
  if (itemType === 'file_change') {
1707
1820
  return 'Drafting response';
@@ -1710,7 +1823,7 @@ function deriveAssistantStreamStatus(event) {
1710
1823
  return 'Drafting response';
1711
1824
  }
1712
1825
  if (itemType === 'reasoning') {
1713
- return 'Analyzing';
1826
+ return 'Planning';
1714
1827
  }
1715
1828
  }
1716
1829
  return null;
@@ -3321,7 +3434,7 @@ function waitForCodexWorkerMessage(worker, streamStatusHandler) {
3321
3434
  }
3322
3435
  function runCodexInWorkerThread(prompt, runOptions, config, streamStatusHandler) {
3323
3436
  return __awaiter(this, void 0, void 0, function () {
3324
- var streamedOptions, codexClient, workerPath, codexClient, error_3, codexClient;
3437
+ var streamedOptions, codexClient, workerPath, codexClient, error_4, codexClient;
3325
3438
  return __generator(this, function (_a) {
3326
3439
  switch (_a.label) {
3327
3440
  case 0:
@@ -3342,11 +3455,11 @@ function runCodexInWorkerThread(prompt, runOptions, config, streamStatusHandler)
3342
3455
  return [4 /*yield*/, runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config, streamStatusHandler)];
3343
3456
  case 6: return [2 /*return*/, _a.sent()];
3344
3457
  case 7:
3345
- error_3 = _a.sent();
3346
- if (!(error_3 instanceof CodexWorkerBootstrapError)) {
3347
- throw error_3;
3458
+ error_4 = _a.sent();
3459
+ if (!(error_4 instanceof CodexWorkerBootstrapError)) {
3460
+ throw error_4;
3348
3461
  }
3349
- console.error('Codex worker bootstrap failed, falling back to in-process run.', error_3);
3462
+ console.error('Codex worker bootstrap failed, falling back to in-process run.', error_4);
3350
3463
  codexClient = getAssistantCodexClient();
3351
3464
  return [4 /*yield*/, codexClient.run(prompt, streamedOptions)];
3352
3465
  case 8: return [2 /*return*/, _a.sent()];
@@ -3384,7 +3497,7 @@ function runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config,
3384
3497
  timeoutMs = ((sanitizedOptions === null || sanitizedOptions === void 0 ? void 0 : sanitizedOptions.timeoutMs) || resolveCodexTimeoutMs()) + 15000;
3385
3498
  timeoutController = new AbortController();
3386
3499
  timeoutPromise = (function () { return __awaiter(_this, void 0, void 0, function () {
3387
- var error_4;
3500
+ var error_5;
3388
3501
  return __generator(this, function (_a) {
3389
3502
  switch (_a.label) {
3390
3503
  case 0:
@@ -3394,11 +3507,11 @@ function runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config,
3394
3507
  _a.sent();
3395
3508
  return [2 /*return*/, { type: 'timeout' }];
3396
3509
  case 2:
3397
- error_4 = _a.sent();
3398
- if ((error_4 === null || error_4 === void 0 ? void 0 : error_4.name) === 'AbortError') {
3510
+ error_5 = _a.sent();
3511
+ if ((error_5 === null || error_5 === void 0 ? void 0 : error_5.name) === 'AbortError') {
3399
3512
  return [2 /*return*/, { type: 'aborted' }];
3400
3513
  }
3401
- throw error_4;
3514
+ throw error_5;
3402
3515
  case 3: return [2 /*return*/];
3403
3516
  }
3404
3517
  });