@resolveio/server-lib 20.14.46 → 20.14.47

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.
@@ -134,6 +134,13 @@ var AI_ASSISTANT_TOOL_MAX_STEPS = 1;
134
134
  var AI_ASSISTANT_DISPLAY_MAX_COLUMNS = 12;
135
135
  var AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS = 20;
136
136
  var AI_ASSISTANT_DISPLAY_STRING_LIMIT = 160;
137
+ var AI_ASSISTANT_PROGRESS_PLACEHOLDER = 'Thinking...';
138
+ var AI_ASSISTANT_PROGRESS_TICK_MS = 8000;
139
+ var AI_ASSISTANT_PROGRESS_TICKS = [
140
+ 'Reviewing context',
141
+ 'Checking data',
142
+ 'Drafting response'
143
+ ];
137
144
  var AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS = [
138
145
  'name',
139
146
  'title',
@@ -781,7 +788,7 @@ function executeAiFormPatch(payload, context) {
781
788
  }
782
789
  function executeAiAssistantCodexRun(payload, context) {
783
790
  return __awaiter(this, void 0, void 0, function () {
784
- var input, message, guardrail, conversation_2, now_2, userMsg, assistantMsg, user, isSuperAdmin, hasInvoiceAccess, customerId, conversation, now, attachments, attachmentData, historyLimit, history, _a, historyLines, assistantContext, prompt, workspaceRoot, codexConfig, runOptions, responseText, directive, cleanedResponseText, assistantContent, toolResult, toolRequest, toolResponse, _b, toolPayload, followupPrompt, followupText, _c, error_1, userDoc, assistantDoc, insertResult;
791
+ var input, message, guardrail, conversation_2, now_2, userMsg, assistantMsg, user, isSuperAdmin, hasInvoiceAccess, customerId, conversation, now, attachments, attachmentData, historyLimit, history, _a, historyLines, assistantContext, prompt, workspaceRoot, codexConfig, runOptions, userDoc, initialProgress, assistantDoc, insertResult, assistantMessageId, progressTracker, assistantContent, toolResult, responseText, directive, cleanedResponseText, toolRequest, toolResponse, _b, toolPayload, followupPrompt, followupText, _c, error_1, error_2, finalNow, finalMetadata, finalAssistantDoc;
785
792
  var _d, _e;
786
793
  return __generator(this, function (_f) {
787
794
  switch (_f.label) {
@@ -884,86 +891,123 @@ function executeAiAssistantCodexRun(payload, context) {
884
891
  approvalPolicy: 'never'
885
892
  }
886
893
  };
887
- return [4 /*yield*/, runCodexInWorkerThread(prompt, runOptions, codexConfig)];
894
+ userDoc = {
895
+ id_conversation: conversation._id,
896
+ role: 'user',
897
+ content: message,
898
+ attachments: attachmentData.attachments,
899
+ createdAt: now,
900
+ updatedAt: now
901
+ };
902
+ initialProgress = ['Thinking'];
903
+ assistantDoc = {
904
+ id_conversation: conversation._id,
905
+ role: 'assistant',
906
+ content: AI_ASSISTANT_PROGRESS_PLACEHOLDER,
907
+ metadata: {
908
+ model: resolveCodexModel(),
909
+ pending: true,
910
+ progress: initialProgress
911
+ },
912
+ createdAt: now,
913
+ updatedAt: now
914
+ };
915
+ return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userDoc)];
888
916
  case 13:
917
+ _f.sent();
918
+ return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(assistantDoc)];
919
+ case 14:
920
+ insertResult = _f.sent();
921
+ assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
922
+ progressTracker = createAssistantProgressTracker(assistantMessageId, initialProgress);
923
+ assistantContent = '';
924
+ toolResult = null;
925
+ _f.label = 15;
926
+ case 15:
927
+ _f.trys.push([15, 30, 31, 32]);
928
+ return [4 /*yield*/, runCodexInWorkerThread(prompt, runOptions, codexConfig)];
929
+ case 16:
889
930
  responseText = _f.sent();
890
931
  directive = extractAssistantMongoDirective(responseText);
891
932
  cleanedResponseText = (directive === null || directive === void 0 ? void 0 : directive.cleaned) || responseText;
892
933
  assistantContent = sanitizeAssistantResponse(cleanedResponseText);
893
- toolResult = null;
894
- if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 24];
934
+ if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 28];
895
935
  toolRequest = buildAssistantToolRequest(directive, input);
896
- _f.label = 14;
897
- case 14:
898
- _f.trys.push([14, 23, , 24]);
899
- if (!(directive.type === 'aggregate')) return [3 /*break*/, 16];
936
+ progressTracker.push(directive.type === 'aggregate' ? 'Running Mongo aggregation' : 'Running Mongo read');
937
+ _f.label = 17;
938
+ case 17:
939
+ _f.trys.push([17, 26, , 27]);
940
+ if (!(directive.type === 'aggregate')) return [3 /*break*/, 19];
900
941
  return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
901
- case 15:
942
+ case 18:
902
943
  _b = _f.sent();
903
- return [3 /*break*/, 18];
904
- case 16: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
905
- case 17:
944
+ return [3 /*break*/, 21];
945
+ case 19: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
946
+ case 20:
906
947
  _b = _f.sent();
907
- _f.label = 18;
908
- case 18:
948
+ _f.label = 21;
949
+ case 21:
909
950
  toolResponse = _b;
910
951
  toolPayload = buildAssistantToolResultPayload(directive, toolResponse);
911
952
  toolResult = toolPayload.result;
953
+ progressTracker.push('Summarizing results');
912
954
  followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
913
- _f.label = 19;
914
- case 19:
915
- _f.trys.push([19, 21, , 22]);
955
+ _f.label = 22;
956
+ case 22:
957
+ _f.trys.push([22, 24, , 25]);
916
958
  return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig)];
917
- case 20:
959
+ case 23:
918
960
  followupText = _f.sent();
919
961
  assistantContent = sanitizeAssistantResponse(followupText);
920
- return [3 /*break*/, 22];
921
- case 21:
962
+ return [3 /*break*/, 25];
963
+ case 24:
922
964
  _c = _f.sent();
923
965
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
924
- return [3 /*break*/, 22];
925
- case 22: return [3 /*break*/, 24];
926
- case 23:
966
+ return [3 /*break*/, 25];
967
+ case 25: return [3 /*break*/, 27];
968
+ case 26:
927
969
  error_1 = _f.sent();
928
970
  assistantContent = buildAssistantToolErrorMessage(error_1, directive, toolRequest);
929
- return [3 /*break*/, 24];
930
- case 24:
931
- userDoc = {
932
- id_conversation: conversation._id,
933
- role: 'user',
934
- content: message,
935
- attachments: attachmentData.attachments,
936
- createdAt: now,
937
- updatedAt: now
938
- };
939
- assistantDoc = {
940
- id_conversation: conversation._id,
941
- role: 'assistant',
942
- content: assistantContent,
943
- metadata: {
944
- model: resolveCodexModel()
945
- },
946
- createdAt: now,
947
- updatedAt: now
948
- };
949
- if (toolResult) {
950
- assistantDoc.metadata = __assign(__assign({}, (assistantDoc.metadata || {})), { tool_result: toolResult });
971
+ return [3 /*break*/, 27];
972
+ case 27: return [3 /*break*/, 29];
973
+ case 28:
974
+ progressTracker.push('Drafting response');
975
+ _f.label = 29;
976
+ case 29: return [3 /*break*/, 32];
977
+ case 30:
978
+ error_2 = _f.sent();
979
+ assistantContent = buildAssistantCodexErrorMessage(error_2);
980
+ return [3 /*break*/, 32];
981
+ case 31:
982
+ progressTracker.stop();
983
+ return [7 /*endfinally*/];
984
+ case 32:
985
+ if (!assistantContent) {
986
+ assistantContent = buildAssistantCodexErrorMessage(null);
951
987
  }
952
- return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userDoc)];
953
- case 25:
988
+ finalNow = new Date();
989
+ finalMetadata = __assign({ model: resolveCodexModel() }, (toolResult ? { tool_result: toolResult } : {}));
990
+ finalAssistantDoc = __assign(__assign({}, assistantDoc), { _id: assistantMessageId, content: assistantContent, metadata: finalMetadata, updatedAt: finalNow });
991
+ if (!assistantMessageId) return [3 /*break*/, 34];
992
+ return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: assistantMessageId }, {
993
+ $set: {
994
+ content: assistantContent,
995
+ metadata: finalMetadata,
996
+ updatedAt: finalNow
997
+ }
998
+ })];
999
+ case 33:
954
1000
  _f.sent();
955
- return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(assistantDoc)];
956
- case 26:
957
- insertResult = _f.sent();
958
- return [4 /*yield*/, touchConversation(conversation._id, now, insertResult._id)];
959
- case 27:
1001
+ _f.label = 34;
1002
+ case 34: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
1003
+ case 35:
960
1004
  _f.sent();
961
- if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 29];
1005
+ if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 37];
962
1006
  return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
963
- case 28:
1007
+ case 36:
964
1008
  _f.sent();
965
- _f.label = 29;
966
- case 29: return [2 /*return*/, __assign({ conversation: conversation, message: assistantDoc }, (toolResult ? { tool_result: toolResult } : {}))];
1009
+ _f.label = 37;
1010
+ case 37: return [2 /*return*/, __assign({ conversation: conversation, message: finalAssistantDoc }, (toolResult ? { tool_result: toolResult } : {}))];
967
1011
  }
968
1012
  });
969
1013
  });
@@ -1341,6 +1385,135 @@ function buildAssistantToolErrorMessage(error, directive, request) {
1341
1385
  }
1342
1386
  return "I couldn't access the requested data. ".concat(routeLine);
1343
1387
  }
1388
+ function normalizeAssistantProgress(items) {
1389
+ var seen = new Set();
1390
+ var cleaned = [];
1391
+ items.forEach(function (item) {
1392
+ var trimmed = String(item || '').trim();
1393
+ if (!trimmed) {
1394
+ return;
1395
+ }
1396
+ var key = trimmed.toLowerCase();
1397
+ if (seen.has(key)) {
1398
+ return;
1399
+ }
1400
+ seen.add(key);
1401
+ cleaned.push(trimmed);
1402
+ });
1403
+ return cleaned;
1404
+ }
1405
+ function updateAssistantProgress(messageId, progress) {
1406
+ return __awaiter(this, void 0, void 0, function () {
1407
+ var normalized, _a;
1408
+ return __generator(this, function (_b) {
1409
+ switch (_b.label) {
1410
+ case 0:
1411
+ normalized = normalizeAssistantProgress(progress);
1412
+ if (!messageId || !normalized.length) {
1413
+ return [2 /*return*/];
1414
+ }
1415
+ _b.label = 1;
1416
+ case 1:
1417
+ _b.trys.push([1, 3, , 4]);
1418
+ return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: messageId, 'metadata.pending': true }, {
1419
+ $set: {
1420
+ 'metadata.pending': true,
1421
+ 'metadata.progress': normalized,
1422
+ updatedAt: new Date()
1423
+ }
1424
+ })];
1425
+ case 2:
1426
+ _b.sent();
1427
+ return [3 /*break*/, 4];
1428
+ case 3:
1429
+ _a = _b.sent();
1430
+ return [3 /*break*/, 4];
1431
+ case 4: return [2 /*return*/];
1432
+ }
1433
+ });
1434
+ });
1435
+ }
1436
+ function createAssistantProgressTracker(messageId, initialProgress) {
1437
+ var _this = this;
1438
+ var progress = normalizeAssistantProgress(initialProgress);
1439
+ var stopped = false;
1440
+ var tickIndex = 0;
1441
+ var updateScheduled = false;
1442
+ var timer = null;
1443
+ var queueProgressUpdate = function () {
1444
+ if (stopped || !messageId || updateScheduled) {
1445
+ return;
1446
+ }
1447
+ updateScheduled = true;
1448
+ setTimeout(function () { return __awaiter(_this, void 0, void 0, function () {
1449
+ var _a;
1450
+ return __generator(this, function (_b) {
1451
+ switch (_b.label) {
1452
+ case 0:
1453
+ updateScheduled = false;
1454
+ if (stopped) {
1455
+ return [2 /*return*/];
1456
+ }
1457
+ _b.label = 1;
1458
+ case 1:
1459
+ _b.trys.push([1, 3, , 4]);
1460
+ return [4 /*yield*/, updateAssistantProgress(messageId, progress)];
1461
+ case 2:
1462
+ _b.sent();
1463
+ return [3 /*break*/, 4];
1464
+ case 3:
1465
+ _a = _b.sent();
1466
+ return [3 /*break*/, 4];
1467
+ case 4: return [2 /*return*/];
1468
+ }
1469
+ });
1470
+ }); }, 0);
1471
+ };
1472
+ if (messageId) {
1473
+ timer = setInterval(function () {
1474
+ if (stopped) {
1475
+ if (timer) {
1476
+ clearInterval(timer);
1477
+ timer = null;
1478
+ }
1479
+ return;
1480
+ }
1481
+ if (tickIndex >= AI_ASSISTANT_PROGRESS_TICKS.length) {
1482
+ if (timer) {
1483
+ clearInterval(timer);
1484
+ timer = null;
1485
+ }
1486
+ return;
1487
+ }
1488
+ var next = AI_ASSISTANT_PROGRESS_TICKS[tickIndex++];
1489
+ progress = normalizeAssistantProgress(__spreadArray(__spreadArray([], __read(progress), false), [next], false));
1490
+ queueProgressUpdate();
1491
+ }, AI_ASSISTANT_PROGRESS_TICK_MS);
1492
+ }
1493
+ return {
1494
+ push: function (item) {
1495
+ if (stopped || !messageId) {
1496
+ return;
1497
+ }
1498
+ progress = normalizeAssistantProgress(__spreadArray(__spreadArray([], __read(progress), false), [item], false));
1499
+ queueProgressUpdate();
1500
+ },
1501
+ stop: function () {
1502
+ stopped = true;
1503
+ if (timer) {
1504
+ clearInterval(timer);
1505
+ timer = null;
1506
+ }
1507
+ }
1508
+ };
1509
+ }
1510
+ function buildAssistantCodexErrorMessage(error) {
1511
+ var raw = normalizeOptionalString(error === null || error === void 0 ? void 0 : error.message);
1512
+ if (raw && /timed out/i.test(raw)) {
1513
+ return 'That took longer than expected. Please try again or narrow the request.';
1514
+ }
1515
+ return 'I ran into an internal error while preparing that response. Please try again.';
1516
+ }
1344
1517
  function isAssistantIdField(key) {
1345
1518
  var normalized = String(key || '').trim().toLowerCase();
1346
1519
  if (!normalized) {
@@ -2233,7 +2406,7 @@ var CodexWorkerBootstrapError = /** @class */ (function (_super) {
2233
2406
  }(Error));
2234
2407
  function runCodexInWorkerThread(prompt, runOptions, config) {
2235
2408
  return __awaiter(this, void 0, void 0, function () {
2236
- var codexClient, workerPath, codexClient, error_2, codexClient;
2409
+ var codexClient, workerPath, codexClient, error_3, codexClient;
2237
2410
  return __generator(this, function (_a) {
2238
2411
  switch (_a.label) {
2239
2412
  case 0:
@@ -2253,11 +2426,11 @@ function runCodexInWorkerThread(prompt, runOptions, config) {
2253
2426
  return [4 /*yield*/, runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config)];
2254
2427
  case 6: return [2 /*return*/, _a.sent()];
2255
2428
  case 7:
2256
- error_2 = _a.sent();
2257
- if (!(error_2 instanceof CodexWorkerBootstrapError)) {
2258
- throw error_2;
2429
+ error_3 = _a.sent();
2430
+ if (!(error_3 instanceof CodexWorkerBootstrapError)) {
2431
+ throw error_3;
2259
2432
  }
2260
- console.error('Codex worker bootstrap failed, falling back to in-process run.', error_2);
2433
+ console.error('Codex worker bootstrap failed, falling back to in-process run.', error_3);
2261
2434
  codexClient = getAssistantCodexClient();
2262
2435
  return [4 /*yield*/, codexClient.run(prompt, runOptions)];
2263
2436
  case 8: return [2 /*return*/, _a.sent()];
@@ -2294,7 +2467,7 @@ function runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config)
2294
2467
  timeoutMs = ((sanitizedOptions === null || sanitizedOptions === void 0 ? void 0 : sanitizedOptions.timeoutMs) || resolveCodexTimeoutMs()) + 15000;
2295
2468
  timeoutController = new AbortController();
2296
2469
  timeoutPromise = (function () { return __awaiter(_this, void 0, void 0, function () {
2297
- var error_3;
2470
+ var error_4;
2298
2471
  return __generator(this, function (_a) {
2299
2472
  switch (_a.label) {
2300
2473
  case 0:
@@ -2304,11 +2477,11 @@ function runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config)
2304
2477
  _a.sent();
2305
2478
  return [2 /*return*/, { type: 'timeout' }];
2306
2479
  case 2:
2307
- error_3 = _a.sent();
2308
- if ((error_3 === null || error_3 === void 0 ? void 0 : error_3.name) === 'AbortError') {
2480
+ error_4 = _a.sent();
2481
+ if ((error_4 === null || error_4 === void 0 ? void 0 : error_4.name) === 'AbortError') {
2309
2482
  return [2 /*return*/, { type: 'aborted' }];
2310
2483
  }
2311
- throw error_3;
2484
+ throw error_4;
2312
2485
  case 3: return [2 /*return*/];
2313
2486
  }
2314
2487
  });