@resolveio/server-lib 20.14.45 → 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.
- package/fixtures/cron-jobs.js +20 -3
- package/fixtures/cron-jobs.js.map +1 -1
- package/methods/ai-terminal.d.ts +28 -1
- package/methods/ai-terminal.js +847 -76
- package/methods/ai-terminal.js.map +1 -1
- package/methods/cron-jobs.js +179 -0
- package/methods/cron-jobs.js.map +1 -1
- package/methods.ts +3 -0
- package/package.json +1 -1
package/methods/ai-terminal.js
CHANGED
|
@@ -101,6 +101,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
101
101
|
exports.loadAiTerminalMethods = loadAiTerminalMethods;
|
|
102
102
|
exports.executeAiAssistantMongoRead = executeAiAssistantMongoRead;
|
|
103
103
|
exports.executeAiAssistantMongoAggregate = executeAiAssistantMongoAggregate;
|
|
104
|
+
exports.extractAssistantMongoDirective = extractAssistantMongoDirective;
|
|
105
|
+
exports.serializeMongoValue = serializeMongoValue;
|
|
106
|
+
exports.flattenForTable = flattenForTable;
|
|
107
|
+
exports.buildDisplayTable = buildDisplayTable;
|
|
108
|
+
exports.formatDisplayTableMarkdown = formatDisplayTableMarkdown;
|
|
104
109
|
var fs_1 = require("fs");
|
|
105
110
|
var events_1 = require("events");
|
|
106
111
|
var os = require("os");
|
|
@@ -125,6 +130,35 @@ var DEFAULT_CODEX_MODEL = 'gpt-5.2-codex';
|
|
|
125
130
|
var DEFAULT_CODEX_TIMEOUT_MS = 180000;
|
|
126
131
|
var AI_ASSISTANT_MONGO_DEFAULT_LIMIT = 20;
|
|
127
132
|
var AI_ASSISTANT_MONGO_MAX_LIMIT = 200;
|
|
133
|
+
var AI_ASSISTANT_TOOL_MAX_STEPS = 1;
|
|
134
|
+
var AI_ASSISTANT_DISPLAY_MAX_COLUMNS = 12;
|
|
135
|
+
var AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS = 20;
|
|
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
|
+
];
|
|
144
|
+
var AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS = [
|
|
145
|
+
'name',
|
|
146
|
+
'title',
|
|
147
|
+
'status',
|
|
148
|
+
'type',
|
|
149
|
+
'stage',
|
|
150
|
+
'state',
|
|
151
|
+
'category',
|
|
152
|
+
'date_created',
|
|
153
|
+
'createdAt',
|
|
154
|
+
'updatedAt',
|
|
155
|
+
'date_updated',
|
|
156
|
+
'date_completed',
|
|
157
|
+
'id_customer',
|
|
158
|
+
'id_client',
|
|
159
|
+
'id_user',
|
|
160
|
+
'id_invoice'
|
|
161
|
+
];
|
|
128
162
|
var AI_ASSISTANT_DATE_FALLBACKS = {
|
|
129
163
|
date_created: 'createdAt',
|
|
130
164
|
createdAt: 'date_created'
|
|
@@ -157,12 +191,29 @@ var AI_ASSISTANT_SENSITIVE_FIELDS = [
|
|
|
157
191
|
var AI_ASSISTANT_CLIENT_SCOPE_CACHE = new Map();
|
|
158
192
|
var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
159
193
|
'You are the ResolveIO in-app AI assistant running with read-only access to the codebase.',
|
|
194
|
+
'Core rules:',
|
|
160
195
|
'- Never share code or file contents. All code is proprietary.',
|
|
161
196
|
'- Do not modify files, run destructive commands, or access databases directly.',
|
|
162
|
-
'- Read-only Mongo access is allowed only via the MONGO_READ
|
|
197
|
+
'- Read-only Mongo access is allowed only via the MONGO_READ/MONGO_AGG directives (see below).',
|
|
163
198
|
'- Do not access secrets, credentials, or user data.',
|
|
164
199
|
'- If the user has a customer portal scope (other.id_customer), only discuss that customer\'s data and what is visible in their customer portal. Never reference other customers or internal/admin-only data. If asked for anything outside the portal, say it isn\'t available.',
|
|
165
200
|
'- Do not assist with hacking, bypassing security, or abuse.',
|
|
201
|
+
'Accuracy & tools:',
|
|
202
|
+
'- 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.',
|
|
203
|
+
'- Prefer running a small Mongo read over asking multiple questions.',
|
|
204
|
+
'- Ask at most one clarifying question only when required to run a query or resolve missing details.',
|
|
205
|
+
'- Use the codebase context to choose correct collections/fields/workflows and use MONGO_READ/MONGO_AGG to answer with real data when needed.',
|
|
206
|
+
'- For direct questions, answer first. Ask a single follow-up only if required to proceed.',
|
|
207
|
+
'Data Presentation:',
|
|
208
|
+
'- Output plain Markdown (NO triple backticks).',
|
|
209
|
+
'- When you reference database results, summarize first, then include a Markdown table.',
|
|
210
|
+
'- When presenting record lists or aggregates, produce a Markdown table (pipes).',
|
|
211
|
+
'- Never show raw JSON dumps.',
|
|
212
|
+
'- Do not include `_id` & `__v` & `id_<other collection _id property>` in tables by default.',
|
|
213
|
+
'- 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.',
|
|
214
|
+
'- Rename `createdAt` to `Created At` and `updatedAt` to `Updated At` in tables.',
|
|
215
|
+
'Response style:',
|
|
216
|
+
'- Keep responses concise: answer first, then 3-8 bullets, then a table when data is involved.',
|
|
166
217
|
'- Prefer high-level explanations and point to routes instead of code. Only mention file paths if explicitly requested.',
|
|
167
218
|
'- When asked where to do something, give the exact screen name and the in-app route as a standalone path starting with "/" so it can be clicked.',
|
|
168
219
|
'- When asked "why is this happening," respond with: cause, trigger, data source(s), and expected vs actual outcome.',
|
|
@@ -174,7 +225,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
174
225
|
'- If access is blocked, name the permission/role needed and how to request it.',
|
|
175
226
|
'- Avoid vague labels like "Operations app"; use the specific screen/workflow name.',
|
|
176
227
|
'- Do not mention other client projects or ask which client; stay within the current project context.',
|
|
177
|
-
'-
|
|
228
|
+
'- Do not add labels like "Customer-facing summary" or "Work ticket summary" and do not include estimated hours.',
|
|
178
229
|
'- Use structured responses by default: short heading, then bullet points. For "how do I" questions, provide a step-by-step list (numbered) with explicit page/screen names and actions.',
|
|
179
230
|
'- When giving steps, include navigation guidance like "Go to <screen>" and "Click/Select/Enter <field>" so the user can follow it exactly.',
|
|
180
231
|
'- If context scope is provided (ex: current page), prioritize that screen in your answer.',
|
|
@@ -183,8 +234,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
183
234
|
'- SUPPORT_TICKET_CREATE: <one-line summary>',
|
|
184
235
|
'- Only include that line when the user clearly wants a ticket created. Do not claim a ticket is created unless you include that line.',
|
|
185
236
|
'- Do not end responses with tentative phrasing like "I could" or "I’m going to." Complete the request or state what is required to proceed.',
|
|
186
|
-
'
|
|
187
|
-
'- For direct questions, answer first. Ask a single follow-up only if required to run a query or resolve missing details.',
|
|
237
|
+
'Mongo directives:',
|
|
188
238
|
'- If you need database data to answer, end your response with a single line exactly in this format:',
|
|
189
239
|
'- MONGO_READ: {"collection":"<name>","query":{...},"options":{"projection":{...},"sort":{...},"limit":20},"permissionView":"</route>"}',
|
|
190
240
|
'- If you need grouped/aggregated data (totals by user, rankings, trends), end your response with a single line exactly in this format:',
|
|
@@ -199,7 +249,7 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
199
249
|
'- For creation-date questions when both date_created and createdAt exist, match both with $or so results are not missed.',
|
|
200
250
|
'- When grouping by fields that can be arrays (drivers, deliveries, routes, chemicals), $unwind first and group by both id and name when available.',
|
|
201
251
|
'- Use MONGO_READ/MONGO_AGG only to produce summaries/snapshots/health checks (not raw dumps) when permitted.',
|
|
202
|
-
'-
|
|
252
|
+
'- If the user explicitly asks for IDs, set options.includeIds: true.',
|
|
203
253
|
'- Keep responses concise and use low reasoning effort.'
|
|
204
254
|
].join('\n');
|
|
205
255
|
var AI_FORM_PATCH_SYSTEM_PROMPT = [
|
|
@@ -738,10 +788,10 @@ function executeAiFormPatch(payload, context) {
|
|
|
738
788
|
}
|
|
739
789
|
function executeAiAssistantCodexRun(payload, context) {
|
|
740
790
|
return __awaiter(this, void 0, void 0, function () {
|
|
741
|
-
var input, message, guardrail, conversation_2, now_2, userMsg, assistantMsg, user, isSuperAdmin, hasInvoiceAccess, customerId, conversation, now, attachments, attachmentData, historyLimit, history, _a, historyLines, prompt, workspaceRoot, codexConfig, runOptions,
|
|
742
|
-
var
|
|
743
|
-
return __generator(this, function (
|
|
744
|
-
switch (
|
|
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;
|
|
792
|
+
var _d, _e;
|
|
793
|
+
return __generator(this, function (_f) {
|
|
794
|
+
switch (_f.label) {
|
|
745
795
|
case 0:
|
|
746
796
|
input = payload || {};
|
|
747
797
|
message = normalizeOptionalString(input.message);
|
|
@@ -755,7 +805,7 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
755
805
|
if (!(guardrail === null || guardrail === void 0 ? void 0 : guardrail.blocked)) return [3 /*break*/, 5];
|
|
756
806
|
return [4 /*yield*/, ensureConversation(input, 'codex')];
|
|
757
807
|
case 1:
|
|
758
|
-
conversation_2 =
|
|
808
|
+
conversation_2 = _f.sent();
|
|
759
809
|
now_2 = new Date();
|
|
760
810
|
userMsg = {
|
|
761
811
|
id_conversation: conversation_2._id,
|
|
@@ -777,13 +827,13 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
777
827
|
};
|
|
778
828
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userMsg)];
|
|
779
829
|
case 2:
|
|
780
|
-
|
|
830
|
+
_f.sent();
|
|
781
831
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(assistantMsg)];
|
|
782
832
|
case 3:
|
|
783
|
-
|
|
833
|
+
_f.sent();
|
|
784
834
|
return [4 /*yield*/, touchConversation(conversation_2._id, now_2)];
|
|
785
835
|
case 4:
|
|
786
|
-
|
|
836
|
+
_f.sent();
|
|
787
837
|
return [2 /*return*/, {
|
|
788
838
|
conversation: conversation_2,
|
|
789
839
|
message: assistantMsg,
|
|
@@ -791,27 +841,27 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
791
841
|
}];
|
|
792
842
|
case 5: return [4 /*yield*/, user_collection_1.Users.findById(context === null || context === void 0 ? void 0 : context.id_user)];
|
|
793
843
|
case 6:
|
|
794
|
-
user =
|
|
795
|
-
isSuperAdmin = !!((
|
|
844
|
+
user = _f.sent();
|
|
845
|
+
isSuperAdmin = !!((_d = user === null || user === void 0 ? void 0 : user.roles) === null || _d === void 0 ? void 0 : _d.super_admin);
|
|
796
846
|
hasInvoiceAccess = userHasInvoiceAccess(user);
|
|
797
|
-
customerId = normalizeOptionalString((
|
|
847
|
+
customerId = normalizeOptionalString((_e = user === null || user === void 0 ? void 0 : user.other) === null || _e === void 0 ? void 0 : _e.id_customer);
|
|
798
848
|
return [4 /*yield*/, ensureConversation(input, 'codex')];
|
|
799
849
|
case 7:
|
|
800
|
-
conversation =
|
|
850
|
+
conversation = _f.sent();
|
|
801
851
|
now = new Date();
|
|
802
852
|
attachments = Array.isArray(input.attachments) ? input.attachments : [];
|
|
803
853
|
return [4 /*yield*/, readAttachmentContents(attachments)];
|
|
804
854
|
case 8:
|
|
805
|
-
attachmentData =
|
|
855
|
+
attachmentData = _f.sent();
|
|
806
856
|
historyLimit = normalizeHistoryLimit(input.max_history);
|
|
807
857
|
if (!(historyLimit > 0)) return [3 /*break*/, 10];
|
|
808
858
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.find({ id_conversation: conversation._id, role: { $in: ['user', 'assistant'] } }, { sort: { createdAt: 1 }, limit: historyLimit * 2 })];
|
|
809
859
|
case 9:
|
|
810
|
-
_a =
|
|
860
|
+
_a = _f.sent();
|
|
811
861
|
return [3 /*break*/, 11];
|
|
812
862
|
case 10:
|
|
813
863
|
_a = [];
|
|
814
|
-
|
|
864
|
+
_f.label = 11;
|
|
815
865
|
case 11:
|
|
816
866
|
history = _a;
|
|
817
867
|
historyLines = [];
|
|
@@ -822,10 +872,11 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
822
872
|
historyLines.push("".concat(role, ": ").concat(content));
|
|
823
873
|
}
|
|
824
874
|
});
|
|
825
|
-
|
|
875
|
+
assistantContext = buildAssistantContext(input, { isSuperAdmin: isSuperAdmin, hasInvoiceAccess: hasInvoiceAccess, customerId: customerId });
|
|
876
|
+
prompt = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
|
|
826
877
|
return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
|
|
827
878
|
case 12:
|
|
828
|
-
workspaceRoot =
|
|
879
|
+
workspaceRoot = _f.sent();
|
|
829
880
|
codexConfig = resolveCodexSettings();
|
|
830
881
|
runOptions = {
|
|
831
882
|
timeoutMs: resolveCodexTimeoutMs(),
|
|
@@ -840,10 +891,6 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
840
891
|
approvalPolicy: 'never'
|
|
841
892
|
}
|
|
842
893
|
};
|
|
843
|
-
return [4 /*yield*/, runCodexInWorkerThread(prompt, runOptions, codexConfig)];
|
|
844
|
-
case 13:
|
|
845
|
-
responseText = _d.sent();
|
|
846
|
-
assistantContent = sanitizeAssistantResponse(responseText);
|
|
847
894
|
userDoc = {
|
|
848
895
|
id_conversation: conversation._id,
|
|
849
896
|
role: 'user',
|
|
@@ -852,44 +899,125 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
852
899
|
createdAt: now,
|
|
853
900
|
updatedAt: now
|
|
854
901
|
};
|
|
902
|
+
initialProgress = ['Thinking'];
|
|
855
903
|
assistantDoc = {
|
|
856
904
|
id_conversation: conversation._id,
|
|
857
905
|
role: 'assistant',
|
|
858
|
-
content:
|
|
906
|
+
content: AI_ASSISTANT_PROGRESS_PLACEHOLDER,
|
|
859
907
|
metadata: {
|
|
860
|
-
model: resolveCodexModel()
|
|
908
|
+
model: resolveCodexModel(),
|
|
909
|
+
pending: true,
|
|
910
|
+
progress: initialProgress
|
|
861
911
|
},
|
|
862
912
|
createdAt: now,
|
|
863
913
|
updatedAt: now
|
|
864
914
|
};
|
|
865
915
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.insertOne(userDoc)];
|
|
866
|
-
case
|
|
867
|
-
|
|
916
|
+
case 13:
|
|
917
|
+
_f.sent();
|
|
868
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;
|
|
869
926
|
case 15:
|
|
870
|
-
|
|
871
|
-
return [4 /*yield*/,
|
|
927
|
+
_f.trys.push([15, 30, 31, 32]);
|
|
928
|
+
return [4 /*yield*/, runCodexInWorkerThread(prompt, runOptions, codexConfig)];
|
|
872
929
|
case 16:
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
930
|
+
responseText = _f.sent();
|
|
931
|
+
directive = extractAssistantMongoDirective(responseText);
|
|
932
|
+
cleanedResponseText = (directive === null || directive === void 0 ? void 0 : directive.cleaned) || responseText;
|
|
933
|
+
assistantContent = sanitizeAssistantResponse(cleanedResponseText);
|
|
934
|
+
if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 28];
|
|
935
|
+
toolRequest = buildAssistantToolRequest(directive, input);
|
|
936
|
+
progressTracker.push(directive.type === 'aggregate' ? 'Running Mongo aggregation' : 'Running Mongo read');
|
|
937
|
+
_f.label = 17;
|
|
876
938
|
case 17:
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
939
|
+
_f.trys.push([17, 26, , 27]);
|
|
940
|
+
if (!(directive.type === 'aggregate')) return [3 /*break*/, 19];
|
|
941
|
+
return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
|
|
942
|
+
case 18:
|
|
943
|
+
_b = _f.sent();
|
|
944
|
+
return [3 /*break*/, 21];
|
|
945
|
+
case 19: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
|
|
946
|
+
case 20:
|
|
947
|
+
_b = _f.sent();
|
|
948
|
+
_f.label = 21;
|
|
949
|
+
case 21:
|
|
950
|
+
toolResponse = _b;
|
|
951
|
+
toolPayload = buildAssistantToolResultPayload(directive, toolResponse);
|
|
952
|
+
toolResult = toolPayload.result;
|
|
953
|
+
progressTracker.push('Summarizing results');
|
|
954
|
+
followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
|
|
955
|
+
_f.label = 22;
|
|
956
|
+
case 22:
|
|
957
|
+
_f.trys.push([22, 24, , 25]);
|
|
958
|
+
return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig)];
|
|
959
|
+
case 23:
|
|
960
|
+
followupText = _f.sent();
|
|
961
|
+
assistantContent = sanitizeAssistantResponse(followupText);
|
|
962
|
+
return [3 /*break*/, 25];
|
|
963
|
+
case 24:
|
|
964
|
+
_c = _f.sent();
|
|
965
|
+
assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
|
|
966
|
+
return [3 /*break*/, 25];
|
|
967
|
+
case 25: return [3 /*break*/, 27];
|
|
968
|
+
case 26:
|
|
969
|
+
error_1 = _f.sent();
|
|
970
|
+
assistantContent = buildAssistantToolErrorMessage(error_1, directive, toolRequest);
|
|
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);
|
|
987
|
+
}
|
|
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:
|
|
1000
|
+
_f.sent();
|
|
1001
|
+
_f.label = 34;
|
|
1002
|
+
case 34: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
|
|
1003
|
+
case 35:
|
|
1004
|
+
_f.sent();
|
|
1005
|
+
if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 37];
|
|
1006
|
+
return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
|
|
1007
|
+
case 36:
|
|
1008
|
+
_f.sent();
|
|
1009
|
+
_f.label = 37;
|
|
1010
|
+
case 37: return [2 /*return*/, __assign({ conversation: conversation, message: finalAssistantDoc }, (toolResult ? { tool_result: toolResult } : {}))];
|
|
883
1011
|
}
|
|
884
1012
|
});
|
|
885
1013
|
});
|
|
886
1014
|
}
|
|
887
1015
|
function executeAiAssistantMongoRead(payload, context) {
|
|
888
1016
|
return __awaiter(this, void 0, void 0, function () {
|
|
889
|
-
var input, collection, _a, user, isSuperAdmin, customerId, dbName, db, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalized, documents, total, sanitizedDocuments;
|
|
890
|
-
var _c;
|
|
891
|
-
return __generator(this, function (
|
|
892
|
-
switch (
|
|
1017
|
+
var input, collection, _a, user, isSuperAdmin, customerId, dbName, db, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalized, documents, total, sanitizedDocuments, includeIds, display;
|
|
1018
|
+
var _c, _d;
|
|
1019
|
+
return __generator(this, function (_e) {
|
|
1020
|
+
switch (_e.label) {
|
|
893
1021
|
case 0:
|
|
894
1022
|
input = payload || {};
|
|
895
1023
|
collection = normalizeOptionalString(input.collection);
|
|
@@ -898,7 +1026,7 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
898
1026
|
}
|
|
899
1027
|
return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
|
|
900
1028
|
case 1:
|
|
901
|
-
_a =
|
|
1029
|
+
_a = _e.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
|
|
902
1030
|
if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
|
|
903
1031
|
throw new Error('AI assistant mongo read: Access denied.');
|
|
904
1032
|
}
|
|
@@ -919,11 +1047,11 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
919
1047
|
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 3];
|
|
920
1048
|
return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
|
|
921
1049
|
case 2:
|
|
922
|
-
_b =
|
|
1050
|
+
_b = _e.sent();
|
|
923
1051
|
return [3 /*break*/, 4];
|
|
924
1052
|
case 3:
|
|
925
1053
|
_b = false;
|
|
926
|
-
|
|
1054
|
+
_e.label = 4;
|
|
927
1055
|
case 4:
|
|
928
1056
|
shouldScopeByClient = _b;
|
|
929
1057
|
clientScopedQuery = shouldScopeByClient
|
|
@@ -933,18 +1061,27 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
933
1061
|
normalized = normalizeAssistantFindOptions(input.options);
|
|
934
1062
|
return [4 /*yield*/, db.collection(collection).find(scopedQuery, normalized.findOptions).toArray()];
|
|
935
1063
|
case 5:
|
|
936
|
-
documents =
|
|
1064
|
+
documents = _e.sent();
|
|
937
1065
|
total = null;
|
|
938
1066
|
if (!normalized.includeTotal) return [3 /*break*/, 7];
|
|
939
1067
|
return [4 /*yield*/, db.collection(collection).countDocuments(scopedQuery)];
|
|
940
1068
|
case 6:
|
|
941
|
-
total =
|
|
942
|
-
|
|
1069
|
+
total = _e.sent();
|
|
1070
|
+
_e.label = 7;
|
|
943
1071
|
case 7:
|
|
944
1072
|
sanitizedDocuments = isSuperAdmin
|
|
945
1073
|
? documents
|
|
946
1074
|
: documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
|
|
947
|
-
|
|
1075
|
+
includeIds = ((_d = input.options) === null || _d === void 0 ? void 0 : _d.includeIds) === true;
|
|
1076
|
+
display = buildDisplayTable(sanitizedDocuments, {
|
|
1077
|
+
includeIds: includeIds,
|
|
1078
|
+
maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
|
|
1079
|
+
maxRows: normalized.findOptions.limit
|
|
1080
|
+
});
|
|
1081
|
+
if (total !== null) {
|
|
1082
|
+
display.total = total;
|
|
1083
|
+
}
|
|
1084
|
+
return [2 /*return*/, __assign({ documents: sanitizedDocuments, total: total, display: display }, (isSuperAdmin ? {
|
|
948
1085
|
debug: {
|
|
949
1086
|
collection: collection,
|
|
950
1087
|
database: dbName,
|
|
@@ -959,10 +1096,10 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
959
1096
|
}
|
|
960
1097
|
function executeAiAssistantMongoAggregate(payload, context) {
|
|
961
1098
|
return __awaiter(this, void 0, void 0, function () {
|
|
962
|
-
var input, collection, _a, user, isSuperAdmin, customerId, dbName, db, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, documents, executedPipeline, fallbackMeta, fallback, fallbackPipeline, fallbackDocs, unwindFallback, fallbackPipeline, fallbackDocs, sanitizedDocuments;
|
|
963
|
-
var _c;
|
|
964
|
-
return __generator(this, function (
|
|
965
|
-
switch (
|
|
1099
|
+
var input, collection, _a, user, isSuperAdmin, customerId, dbName, db, baseQuery, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, documents, executedPipeline, fallbackMeta, fallback, fallbackPipeline, fallbackDocs, unwindFallback, fallbackPipeline, fallbackDocs, sanitizedDocuments, includeIds, display;
|
|
1100
|
+
var _c, _d;
|
|
1101
|
+
return __generator(this, function (_e) {
|
|
1102
|
+
switch (_e.label) {
|
|
966
1103
|
case 0:
|
|
967
1104
|
input = payload || {};
|
|
968
1105
|
collection = normalizeOptionalString(input.collection);
|
|
@@ -971,7 +1108,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
971
1108
|
}
|
|
972
1109
|
return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
|
|
973
1110
|
case 1:
|
|
974
|
-
_a =
|
|
1111
|
+
_a = _e.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
|
|
975
1112
|
if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
|
|
976
1113
|
throw new Error('AI assistant mongo aggregate: Access denied.');
|
|
977
1114
|
}
|
|
@@ -992,11 +1129,11 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
992
1129
|
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 3];
|
|
993
1130
|
return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
|
|
994
1131
|
case 2:
|
|
995
|
-
_b =
|
|
1132
|
+
_b = _e.sent();
|
|
996
1133
|
return [3 /*break*/, 4];
|
|
997
1134
|
case 3:
|
|
998
1135
|
_b = false;
|
|
999
|
-
|
|
1136
|
+
_e.label = 4;
|
|
1000
1137
|
case 4:
|
|
1001
1138
|
shouldScopeByClient = _b;
|
|
1002
1139
|
clientScopedQuery = shouldScopeByClient
|
|
@@ -1014,7 +1151,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
1014
1151
|
.aggregate(limitedPipeline, normalizedOptions.aggregateOptions)
|
|
1015
1152
|
.toArray()];
|
|
1016
1153
|
case 5:
|
|
1017
|
-
documents =
|
|
1154
|
+
documents = _e.sent();
|
|
1018
1155
|
executedPipeline = limitedPipeline;
|
|
1019
1156
|
fallbackMeta = {};
|
|
1020
1157
|
if (!!documents.length) return [3 /*break*/, 7];
|
|
@@ -1027,13 +1164,13 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
1027
1164
|
.aggregate(fallbackPipeline, normalizedOptions.aggregateOptions)
|
|
1028
1165
|
.toArray()];
|
|
1029
1166
|
case 6:
|
|
1030
|
-
fallbackDocs =
|
|
1167
|
+
fallbackDocs = _e.sent();
|
|
1031
1168
|
if (fallbackDocs.length) {
|
|
1032
1169
|
documents = fallbackDocs;
|
|
1033
1170
|
executedPipeline = fallbackPipeline;
|
|
1034
1171
|
fallbackMeta.dateField.used = true;
|
|
1035
1172
|
}
|
|
1036
|
-
|
|
1173
|
+
_e.label = 7;
|
|
1037
1174
|
case 7:
|
|
1038
1175
|
if (!(documents.length <= 1)) return [3 /*break*/, 9];
|
|
1039
1176
|
unwindFallback = resolveAggregateUnwindFallback(executedPipeline);
|
|
@@ -1045,18 +1182,24 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
1045
1182
|
.aggregate(fallbackPipeline, normalizedOptions.aggregateOptions)
|
|
1046
1183
|
.toArray()];
|
|
1047
1184
|
case 8:
|
|
1048
|
-
fallbackDocs =
|
|
1185
|
+
fallbackDocs = _e.sent();
|
|
1049
1186
|
if (fallbackDocs.length > documents.length) {
|
|
1050
1187
|
documents = fallbackDocs;
|
|
1051
1188
|
executedPipeline = fallbackPipeline;
|
|
1052
1189
|
fallbackMeta.unwind.used = true;
|
|
1053
1190
|
}
|
|
1054
|
-
|
|
1191
|
+
_e.label = 9;
|
|
1055
1192
|
case 9:
|
|
1056
1193
|
sanitizedDocuments = isSuperAdmin
|
|
1057
1194
|
? documents
|
|
1058
1195
|
: documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
|
|
1059
|
-
|
|
1196
|
+
includeIds = ((_d = input.options) === null || _d === void 0 ? void 0 : _d.includeIds) === true;
|
|
1197
|
+
display = buildDisplayTable(sanitizedDocuments, {
|
|
1198
|
+
includeIds: includeIds,
|
|
1199
|
+
maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
|
|
1200
|
+
maxRows: normalizedOptions.limit || sanitizedDocuments.length
|
|
1201
|
+
});
|
|
1202
|
+
return [2 /*return*/, __assign({ documents: sanitizedDocuments, display: display }, (isSuperAdmin ? {
|
|
1060
1203
|
debug: {
|
|
1061
1204
|
collection: collection,
|
|
1062
1205
|
database: dbName,
|
|
@@ -1071,6 +1214,607 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
1071
1214
|
});
|
|
1072
1215
|
});
|
|
1073
1216
|
}
|
|
1217
|
+
function extractAssistantMongoDirective(content) {
|
|
1218
|
+
var lines = String(content || '').split('\n');
|
|
1219
|
+
var directiveIndex = -1;
|
|
1220
|
+
var directiveLine = '';
|
|
1221
|
+
var directiveType = null;
|
|
1222
|
+
var directiveIndexes = new Set();
|
|
1223
|
+
lines.forEach(function (line, index) {
|
|
1224
|
+
var normalized = line.trim().replace(/^[-*]+\s*/, '');
|
|
1225
|
+
var upper = normalized.toUpperCase();
|
|
1226
|
+
if (upper.startsWith('MONGO_READ:')) {
|
|
1227
|
+
directiveIndexes.add(index);
|
|
1228
|
+
directiveIndex = index;
|
|
1229
|
+
directiveLine = normalized;
|
|
1230
|
+
directiveType = 'read';
|
|
1231
|
+
return;
|
|
1232
|
+
}
|
|
1233
|
+
if (upper.startsWith('MONGO_AGG:') || upper.startsWith('MONGO_AGGREGATE:')) {
|
|
1234
|
+
directiveIndexes.add(index);
|
|
1235
|
+
directiveIndex = index;
|
|
1236
|
+
directiveLine = normalized;
|
|
1237
|
+
directiveType = 'aggregate';
|
|
1238
|
+
}
|
|
1239
|
+
});
|
|
1240
|
+
if (directiveIndex === -1 || !directiveType) {
|
|
1241
|
+
return null;
|
|
1242
|
+
}
|
|
1243
|
+
var colonIndex = directiveLine.indexOf(':');
|
|
1244
|
+
var after = colonIndex >= 0 ? directiveLine.slice(colonIndex + 1).trim() : '';
|
|
1245
|
+
var parsed = after ? parseJsonObject(after) : null;
|
|
1246
|
+
var payload = parsed && typeof parsed === 'object' ? parsed : null;
|
|
1247
|
+
var cleaned = lines.filter(function (_, index) { return !directiveIndexes.has(index); }).join('\n').trim();
|
|
1248
|
+
return {
|
|
1249
|
+
type: directiveType,
|
|
1250
|
+
payload: payload,
|
|
1251
|
+
cleaned: cleaned,
|
|
1252
|
+
rawLine: directiveLine
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
function buildAssistantToolRequest(directive, payload) {
|
|
1256
|
+
var _a;
|
|
1257
|
+
var base = directive.payload && typeof directive.payload === 'object' ? directive.payload : {};
|
|
1258
|
+
var request = __assign({}, base);
|
|
1259
|
+
var route = normalizeOptionalString((_a = payload === null || payload === void 0 ? void 0 : payload.context) === null || _a === void 0 ? void 0 : _a.route);
|
|
1260
|
+
if (!request.permissionView && route) {
|
|
1261
|
+
request.permissionView = route;
|
|
1262
|
+
}
|
|
1263
|
+
if (!request.id_client) {
|
|
1264
|
+
var idClient = normalizeOptionalString(payload === null || payload === void 0 ? void 0 : payload.id_client);
|
|
1265
|
+
if (idClient) {
|
|
1266
|
+
request.id_client = idClient;
|
|
1267
|
+
}
|
|
1268
|
+
}
|
|
1269
|
+
if (!request.mongo && (payload === null || payload === void 0 ? void 0 : payload.mongo)) {
|
|
1270
|
+
request.mongo = payload.mongo;
|
|
1271
|
+
}
|
|
1272
|
+
return request;
|
|
1273
|
+
}
|
|
1274
|
+
function buildAssistantToolResultPayload(directive, toolResponse) {
|
|
1275
|
+
var _a;
|
|
1276
|
+
var directivePayload = directive.payload || {};
|
|
1277
|
+
var documents = Array.isArray(toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.documents) ? toolResponse.documents : [];
|
|
1278
|
+
var includeIds = ((_a = directivePayload === null || directivePayload === void 0 ? void 0 : directivePayload.options) === null || _a === void 0 ? void 0 : _a.includeIds) === true;
|
|
1279
|
+
var display = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.display) && typeof toolResponse.display === 'object'
|
|
1280
|
+
? toolResponse.display
|
|
1281
|
+
: buildDisplayTable(documents, {
|
|
1282
|
+
includeIds: includeIds,
|
|
1283
|
+
maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
|
|
1284
|
+
maxRows: AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS
|
|
1285
|
+
});
|
|
1286
|
+
var trimmedDisplay = trimDisplayTable(display, {
|
|
1287
|
+
maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
|
|
1288
|
+
maxRows: AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS
|
|
1289
|
+
});
|
|
1290
|
+
var total = typeof (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.total) === 'number' ? toolResponse.total : null;
|
|
1291
|
+
var rowCount = documents.length || trimmedDisplay.rowCount;
|
|
1292
|
+
var collection = normalizeOptionalString(directivePayload === null || directivePayload === void 0 ? void 0 : directivePayload.collection) || '';
|
|
1293
|
+
var result = {
|
|
1294
|
+
type: directive.type === 'aggregate' ? 'mongo_agg' : 'mongo_read',
|
|
1295
|
+
input: directivePayload,
|
|
1296
|
+
output: {
|
|
1297
|
+
display: trimmedDisplay,
|
|
1298
|
+
total: total !== null ? total : undefined,
|
|
1299
|
+
collection: collection || undefined,
|
|
1300
|
+
rowCount: rowCount,
|
|
1301
|
+
columns: trimmedDisplay.columns,
|
|
1302
|
+
truncated: trimmedDisplay.truncated
|
|
1303
|
+
}
|
|
1304
|
+
};
|
|
1305
|
+
return {
|
|
1306
|
+
result: result,
|
|
1307
|
+
prompt: buildAssistantToolResultPrompt(result)
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1310
|
+
function buildAssistantToolResultPrompt(result) {
|
|
1311
|
+
var _a, _b;
|
|
1312
|
+
var lines = ['Tool Result:'];
|
|
1313
|
+
lines.push("Type: ".concat(result.type));
|
|
1314
|
+
if (result.output.collection) {
|
|
1315
|
+
lines.push("Collection: ".concat(result.output.collection));
|
|
1316
|
+
}
|
|
1317
|
+
lines.push("Row count: ".concat(result.output.rowCount));
|
|
1318
|
+
if (typeof result.output.total === 'number') {
|
|
1319
|
+
lines.push("Total: ".concat(result.output.total));
|
|
1320
|
+
}
|
|
1321
|
+
if (Array.isArray(result.output.columns) && result.output.columns.length) {
|
|
1322
|
+
lines.push("Columns: ".concat(result.output.columns.join(', ')));
|
|
1323
|
+
}
|
|
1324
|
+
if ((_b = (_a = result.output.display) === null || _a === void 0 ? void 0 : _a.rows) === null || _b === void 0 ? void 0 : _b.length) {
|
|
1325
|
+
lines.push('Preview:');
|
|
1326
|
+
lines.push(formatDisplayTableMarkdown(result.output.display));
|
|
1327
|
+
}
|
|
1328
|
+
else {
|
|
1329
|
+
lines.push('Preview: (no rows)');
|
|
1330
|
+
}
|
|
1331
|
+
return lines.join('\n');
|
|
1332
|
+
}
|
|
1333
|
+
function buildAssistantCodexToolFollowupPrompt(message, attachmentText, historyText, contextText, toolResultText) {
|
|
1334
|
+
var trimmedContext = normalizeOptionalString(contextText);
|
|
1335
|
+
var contextBlock = trimmedContext ? "\n\nContext:\n".concat(trimmedContext) : '';
|
|
1336
|
+
var trimmedHistory = normalizeOptionalString(historyText);
|
|
1337
|
+
var historyBlock = trimmedHistory ? "\n\nConversation so far:\n".concat(trimmedHistory) : '';
|
|
1338
|
+
var toolBlock = toolResultText ? "\n\nTool Result:\n".concat(toolResultText) : '';
|
|
1339
|
+
var instruction = '\n\nInstruction:\nNow answer the user. Do NOT output another MONGO_* directive. Output plain Markdown. Summarize first, then include a Markdown table.';
|
|
1340
|
+
return "System:\n".concat(AI_ASSISTANT_SYSTEM_PROMPT).concat(contextBlock).concat(historyBlock, "\n\nUser:\n").concat(message).concat(attachmentText || '').concat(toolBlock).concat(instruction).trim();
|
|
1341
|
+
}
|
|
1342
|
+
function buildAssistantToolFallbackResponse(result) {
|
|
1343
|
+
var _a, _b;
|
|
1344
|
+
var lines = ['Here is a data snapshot based on the tool result:'];
|
|
1345
|
+
if (result.output.collection) {
|
|
1346
|
+
lines.push("- Collection: ".concat(result.output.collection));
|
|
1347
|
+
}
|
|
1348
|
+
lines.push("- Rows returned: ".concat(result.output.rowCount));
|
|
1349
|
+
if (typeof result.output.total === 'number') {
|
|
1350
|
+
lines.push("- Total: ".concat(result.output.total));
|
|
1351
|
+
}
|
|
1352
|
+
if ((_b = (_a = result.output.display) === null || _a === void 0 ? void 0 : _a.rows) === null || _b === void 0 ? void 0 : _b.length) {
|
|
1353
|
+
lines.push('');
|
|
1354
|
+
lines.push(formatDisplayTableMarkdown(result.output.display));
|
|
1355
|
+
}
|
|
1356
|
+
return lines.join('\n').trim();
|
|
1357
|
+
}
|
|
1358
|
+
function buildAssistantToolErrorMessage(error, directive, request) {
|
|
1359
|
+
var _a, _b;
|
|
1360
|
+
var rawMessage = normalizeOptionalString(error === null || error === void 0 ? void 0 : error.message) || 'Unable to access data.';
|
|
1361
|
+
var normalized = rawMessage.toLowerCase();
|
|
1362
|
+
var routeHint = normalizeOptionalString(request === null || request === void 0 ? void 0 : request.permissionView)
|
|
1363
|
+
|| normalizeOptionalString((_a = directive.payload) === null || _a === void 0 ? void 0 : _a.permissionView);
|
|
1364
|
+
var collection = normalizeOptionalString(request === null || request === void 0 ? void 0 : request.collection) || normalizeOptionalString((_b = directive.payload) === null || _b === void 0 ? void 0 : _b.collection);
|
|
1365
|
+
var routeLine = routeHint
|
|
1366
|
+
? "Open ".concat(routeHint, " in the app to view this data or request access.")
|
|
1367
|
+
: 'Open the related screen in the app to view this data or request access.';
|
|
1368
|
+
if (!routeHint && collection && requiresInvoicePermission(collection)) {
|
|
1369
|
+
routeLine = 'Open /invoice/list or /report/invoice to view this data or request access.';
|
|
1370
|
+
}
|
|
1371
|
+
if (normalized.includes('permission scope required')) {
|
|
1372
|
+
return "I need a permission scope to access that data. ".concat(routeLine);
|
|
1373
|
+
}
|
|
1374
|
+
if (normalized.includes('access denied')) {
|
|
1375
|
+
if (collection && requiresInvoicePermission(collection)) {
|
|
1376
|
+
return "Invoice access is required to view that data. ".concat(routeLine);
|
|
1377
|
+
}
|
|
1378
|
+
return "You don't have permission to view that data. ".concat(routeLine);
|
|
1379
|
+
}
|
|
1380
|
+
if (normalized.includes('database access denied')) {
|
|
1381
|
+
return "Database access is restricted for that request. ".concat(routeLine);
|
|
1382
|
+
}
|
|
1383
|
+
if (normalized.includes('collection is required')) {
|
|
1384
|
+
return 'I need a valid collection to read from. Please specify which screen or dataset you want.';
|
|
1385
|
+
}
|
|
1386
|
+
return "I couldn't access the requested data. ".concat(routeLine);
|
|
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
|
+
}
|
|
1517
|
+
function isAssistantIdField(key) {
|
|
1518
|
+
var normalized = String(key || '').trim().toLowerCase();
|
|
1519
|
+
if (!normalized) {
|
|
1520
|
+
return false;
|
|
1521
|
+
}
|
|
1522
|
+
if (normalized === '_id' || normalized === '__v') {
|
|
1523
|
+
return true;
|
|
1524
|
+
}
|
|
1525
|
+
if (normalized.startsWith('id_')) {
|
|
1526
|
+
return true;
|
|
1527
|
+
}
|
|
1528
|
+
var parts = normalized.split('.');
|
|
1529
|
+
var last = parts[parts.length - 1] || '';
|
|
1530
|
+
return last.startsWith('id_');
|
|
1531
|
+
}
|
|
1532
|
+
function isMongoObjectId(value) {
|
|
1533
|
+
if (!value || typeof value !== 'object') {
|
|
1534
|
+
return false;
|
|
1535
|
+
}
|
|
1536
|
+
if (typeof value.toHexString === 'function') {
|
|
1537
|
+
return true;
|
|
1538
|
+
}
|
|
1539
|
+
return value._bsontype === 'ObjectId';
|
|
1540
|
+
}
|
|
1541
|
+
function isPlainObject(value) {
|
|
1542
|
+
return !!value && typeof value === 'object' && Object.prototype.toString.call(value) === '[object Object]';
|
|
1543
|
+
}
|
|
1544
|
+
function normalizeColumnPriorityKey(column) {
|
|
1545
|
+
var trimmed = String(column || '').trim();
|
|
1546
|
+
if (!trimmed) {
|
|
1547
|
+
return '';
|
|
1548
|
+
}
|
|
1549
|
+
var base = trimmed.includes('.') ? trimmed.split('.').pop() || trimmed : trimmed;
|
|
1550
|
+
return base.toLowerCase();
|
|
1551
|
+
}
|
|
1552
|
+
function formatDisplayColumnName(column) {
|
|
1553
|
+
var trimmed = String(column || '').trim();
|
|
1554
|
+
if (!trimmed) {
|
|
1555
|
+
return '';
|
|
1556
|
+
}
|
|
1557
|
+
if (trimmed === '_id') {
|
|
1558
|
+
return 'id';
|
|
1559
|
+
}
|
|
1560
|
+
if (trimmed === '_group') {
|
|
1561
|
+
return 'Group';
|
|
1562
|
+
}
|
|
1563
|
+
var normalized = trimmed.replace(/[\s_]+/g, '').toLowerCase();
|
|
1564
|
+
if (normalized === 'createdat') {
|
|
1565
|
+
return 'Created At';
|
|
1566
|
+
}
|
|
1567
|
+
if (normalized === 'updatedat') {
|
|
1568
|
+
return 'Updated At';
|
|
1569
|
+
}
|
|
1570
|
+
return trimmed;
|
|
1571
|
+
}
|
|
1572
|
+
function truncateDisplayText(value, maxLength) {
|
|
1573
|
+
if (maxLength === void 0) { maxLength = AI_ASSISTANT_DISPLAY_STRING_LIMIT; }
|
|
1574
|
+
if (!value) {
|
|
1575
|
+
return value;
|
|
1576
|
+
}
|
|
1577
|
+
if (value.length <= maxLength) {
|
|
1578
|
+
return value;
|
|
1579
|
+
}
|
|
1580
|
+
var sliceLength = Math.max(0, maxLength - 3);
|
|
1581
|
+
return "".concat(value.slice(0, sliceLength), "...");
|
|
1582
|
+
}
|
|
1583
|
+
function serializeMongoValue(value, maxLength) {
|
|
1584
|
+
if (maxLength === void 0) { maxLength = AI_ASSISTANT_DISPLAY_STRING_LIMIT; }
|
|
1585
|
+
if (value === null || value === undefined) {
|
|
1586
|
+
return null;
|
|
1587
|
+
}
|
|
1588
|
+
if (typeof value === 'number' || typeof value === 'boolean') {
|
|
1589
|
+
return value;
|
|
1590
|
+
}
|
|
1591
|
+
if (typeof value === 'string') {
|
|
1592
|
+
return truncateDisplayText(value, maxLength);
|
|
1593
|
+
}
|
|
1594
|
+
if (value instanceof Date) {
|
|
1595
|
+
return value.toISOString();
|
|
1596
|
+
}
|
|
1597
|
+
if (isMongoObjectId(value)) {
|
|
1598
|
+
try {
|
|
1599
|
+
var hex = typeof value.toHexString === 'function' ? value.toHexString() : String(value);
|
|
1600
|
+
var shortened = hex.length > 8 ? hex.slice(0, 8) : hex;
|
|
1601
|
+
return truncateDisplayText(shortened, maxLength);
|
|
1602
|
+
}
|
|
1603
|
+
catch (_a) {
|
|
1604
|
+
return truncateDisplayText(String(value), maxLength);
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
if (Array.isArray(value)) {
|
|
1608
|
+
var preview = value.slice(0, 3).map(function (entry) { return serializeMongoValue(entry, maxLength); });
|
|
1609
|
+
var compact = preview.map(function (entry) { return (entry === null || entry === undefined) ? '' : String(entry); }).join(', ');
|
|
1610
|
+
var suffix = value.length > 3 ? ', ...' : '';
|
|
1611
|
+
return truncateDisplayText("[".concat(compact).concat(suffix, "]"), maxLength);
|
|
1612
|
+
}
|
|
1613
|
+
if (typeof value === 'object') {
|
|
1614
|
+
var text = '';
|
|
1615
|
+
try {
|
|
1616
|
+
text = JSON.stringify(value);
|
|
1617
|
+
}
|
|
1618
|
+
catch (_b) {
|
|
1619
|
+
text = String(value);
|
|
1620
|
+
}
|
|
1621
|
+
if (!text || text === '[object Object]') {
|
|
1622
|
+
try {
|
|
1623
|
+
text = JSON.stringify(value, null, 2);
|
|
1624
|
+
}
|
|
1625
|
+
catch (_c) {
|
|
1626
|
+
text = String(value);
|
|
1627
|
+
}
|
|
1628
|
+
}
|
|
1629
|
+
return truncateDisplayText(text, maxLength);
|
|
1630
|
+
}
|
|
1631
|
+
return truncateDisplayText(String(value), maxLength);
|
|
1632
|
+
}
|
|
1633
|
+
function flattenForTable(doc) {
|
|
1634
|
+
var result = {};
|
|
1635
|
+
if (!doc || typeof doc !== 'object') {
|
|
1636
|
+
return result;
|
|
1637
|
+
}
|
|
1638
|
+
if (Object.prototype.hasOwnProperty.call(doc, '_id')) {
|
|
1639
|
+
var idValue_1 = doc._id;
|
|
1640
|
+
if (idValue_1 !== null && idValue_1 !== undefined) {
|
|
1641
|
+
if (isPlainObject(idValue_1) && !isMongoObjectId(idValue_1) && !(idValue_1 instanceof Date)) {
|
|
1642
|
+
Object.keys(idValue_1).forEach(function (key) {
|
|
1643
|
+
if (!key || Object.prototype.hasOwnProperty.call(result, key)) {
|
|
1644
|
+
return;
|
|
1645
|
+
}
|
|
1646
|
+
result[key] = idValue_1[key];
|
|
1647
|
+
});
|
|
1648
|
+
}
|
|
1649
|
+
else if (!Object.prototype.hasOwnProperty.call(result, '_group')) {
|
|
1650
|
+
result._group = idValue_1;
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
}
|
|
1654
|
+
Object.keys(doc).forEach(function (key) {
|
|
1655
|
+
if (key === '_id') {
|
|
1656
|
+
return;
|
|
1657
|
+
}
|
|
1658
|
+
var value = doc[key];
|
|
1659
|
+
if (value === undefined) {
|
|
1660
|
+
return;
|
|
1661
|
+
}
|
|
1662
|
+
if (isPlainObject(value) && !isMongoObjectId(value) && !(value instanceof Date)) {
|
|
1663
|
+
var nestedKeys = Object.keys(value);
|
|
1664
|
+
if (nestedKeys.length && nestedKeys.length <= 6) {
|
|
1665
|
+
nestedKeys.forEach(function (nestedKey) {
|
|
1666
|
+
if (!nestedKey) {
|
|
1667
|
+
return;
|
|
1668
|
+
}
|
|
1669
|
+
var nestedValue = value[nestedKey];
|
|
1670
|
+
if (nestedValue === undefined) {
|
|
1671
|
+
return;
|
|
1672
|
+
}
|
|
1673
|
+
result["".concat(key, ".").concat(nestedKey)] = nestedValue;
|
|
1674
|
+
});
|
|
1675
|
+
return;
|
|
1676
|
+
}
|
|
1677
|
+
}
|
|
1678
|
+
result[key] = value;
|
|
1679
|
+
});
|
|
1680
|
+
return result;
|
|
1681
|
+
}
|
|
1682
|
+
function buildDisplayTable(docs, options) {
|
|
1683
|
+
var rowsRaw = Array.isArray(docs) ? docs.map(function (doc) { return flattenForTable(doc); }) : [];
|
|
1684
|
+
var stats = new Map();
|
|
1685
|
+
rowsRaw.forEach(function (row) {
|
|
1686
|
+
Object.keys(row).forEach(function (key) {
|
|
1687
|
+
var value = row[key];
|
|
1688
|
+
var entry = stats.get(key) || { nonEmpty: 0, objectLike: 0 };
|
|
1689
|
+
if (!isEmptyDisplayValue(value)) {
|
|
1690
|
+
entry.nonEmpty += 1;
|
|
1691
|
+
}
|
|
1692
|
+
if (isDisplayObjectLike(value)) {
|
|
1693
|
+
entry.objectLike += 1;
|
|
1694
|
+
}
|
|
1695
|
+
stats.set(key, entry);
|
|
1696
|
+
});
|
|
1697
|
+
});
|
|
1698
|
+
var columns = Array.from(stats.keys()).filter(function (key) {
|
|
1699
|
+
var entry = stats.get(key);
|
|
1700
|
+
if (!entry || entry.nonEmpty === 0) {
|
|
1701
|
+
return false;
|
|
1702
|
+
}
|
|
1703
|
+
if (!(options === null || options === void 0 ? void 0 : options.includeIds) && isAssistantIdField(key)) {
|
|
1704
|
+
return false;
|
|
1705
|
+
}
|
|
1706
|
+
if (entry.objectLike / Math.max(entry.nonEmpty, 1) > 0.5) {
|
|
1707
|
+
return false;
|
|
1708
|
+
}
|
|
1709
|
+
return true;
|
|
1710
|
+
});
|
|
1711
|
+
if (!columns.length && rowsRaw.length) {
|
|
1712
|
+
columns = Object.keys(rowsRaw[0] || {}).filter(function (key) { return (options === null || options === void 0 ? void 0 : options.includeIds) || !isAssistantIdField(key); });
|
|
1713
|
+
}
|
|
1714
|
+
var priorityFields = (options === null || options === void 0 ? void 0 : options.priorityFields) || AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS;
|
|
1715
|
+
var priorityMap = new Map(priorityFields.map(function (field, index) { return [field.toLowerCase(), index]; }));
|
|
1716
|
+
columns.sort(function (a, b) {
|
|
1717
|
+
var _a, _b, _c, _d;
|
|
1718
|
+
var aPriority = (_a = priorityMap.get(normalizeColumnPriorityKey(a))) !== null && _a !== void 0 ? _a : 999;
|
|
1719
|
+
var bPriority = (_b = priorityMap.get(normalizeColumnPriorityKey(b))) !== null && _b !== void 0 ? _b : 999;
|
|
1720
|
+
if (aPriority !== bPriority) {
|
|
1721
|
+
return aPriority - bPriority;
|
|
1722
|
+
}
|
|
1723
|
+
var aCount = ((_c = stats.get(a)) === null || _c === void 0 ? void 0 : _c.nonEmpty) || 0;
|
|
1724
|
+
var bCount = ((_d = stats.get(b)) === null || _d === void 0 ? void 0 : _d.nonEmpty) || 0;
|
|
1725
|
+
if (aCount !== bCount) {
|
|
1726
|
+
return bCount - aCount;
|
|
1727
|
+
}
|
|
1728
|
+
return a.localeCompare(b);
|
|
1729
|
+
});
|
|
1730
|
+
var maxColumns = typeof (options === null || options === void 0 ? void 0 : options.maxColumns) === 'number'
|
|
1731
|
+
? Math.max(options.maxColumns, 0)
|
|
1732
|
+
: AI_ASSISTANT_DISPLAY_MAX_COLUMNS;
|
|
1733
|
+
if (maxColumns && columns.length > maxColumns) {
|
|
1734
|
+
columns = columns.slice(0, maxColumns);
|
|
1735
|
+
}
|
|
1736
|
+
var columnLabels = columns.map(function (column) { return formatDisplayColumnName(column) || column; });
|
|
1737
|
+
var maxRows = typeof (options === null || options === void 0 ? void 0 : options.maxRows) === 'number'
|
|
1738
|
+
? Math.max(options.maxRows, 0)
|
|
1739
|
+
: rowsRaw.length;
|
|
1740
|
+
var limitedRows = maxRows ? rowsRaw.slice(0, maxRows) : [];
|
|
1741
|
+
var rows = limitedRows.map(function (row) {
|
|
1742
|
+
var next = {};
|
|
1743
|
+
columns.forEach(function (column, index) {
|
|
1744
|
+
var label = columnLabels[index] || column;
|
|
1745
|
+
next[label] = serializeMongoValue(row[column]);
|
|
1746
|
+
});
|
|
1747
|
+
return next;
|
|
1748
|
+
});
|
|
1749
|
+
return {
|
|
1750
|
+
columns: columnLabels,
|
|
1751
|
+
rows: rows,
|
|
1752
|
+
rowCount: rowsRaw.length,
|
|
1753
|
+
truncated: rowsRaw.length > maxRows || columns.length > maxColumns,
|
|
1754
|
+
includeIds: (options === null || options === void 0 ? void 0 : options.includeIds) === true
|
|
1755
|
+
};
|
|
1756
|
+
}
|
|
1757
|
+
function trimDisplayTable(display, options) {
|
|
1758
|
+
if (!display || !Array.isArray(display.columns)) {
|
|
1759
|
+
return display;
|
|
1760
|
+
}
|
|
1761
|
+
var rowsSource = Array.isArray(display.rows) ? display.rows : [];
|
|
1762
|
+
var maxColumns = typeof (options === null || options === void 0 ? void 0 : options.maxColumns) === 'number'
|
|
1763
|
+
? Math.max(options.maxColumns, 0)
|
|
1764
|
+
: display.columns.length;
|
|
1765
|
+
var maxRows = typeof (options === null || options === void 0 ? void 0 : options.maxRows) === 'number'
|
|
1766
|
+
? Math.max(options.maxRows, 0)
|
|
1767
|
+
: rowsSource.length;
|
|
1768
|
+
var columns = maxColumns ? display.columns.slice(0, maxColumns) : [];
|
|
1769
|
+
var rows = maxRows ? rowsSource.slice(0, maxRows).map(function (row) {
|
|
1770
|
+
var next = {};
|
|
1771
|
+
columns.forEach(function (column) {
|
|
1772
|
+
next[column] = row === null || row === void 0 ? void 0 : row[column];
|
|
1773
|
+
});
|
|
1774
|
+
return next;
|
|
1775
|
+
}) : [];
|
|
1776
|
+
return __assign(__assign({}, display), { columns: columns, rows: rows, truncated: display.truncated || display.columns.length > maxColumns || rowsSource.length > maxRows });
|
|
1777
|
+
}
|
|
1778
|
+
function formatDisplayTableMarkdown(display) {
|
|
1779
|
+
if (!display || !Array.isArray(display.columns) || !display.columns.length) {
|
|
1780
|
+
return '';
|
|
1781
|
+
}
|
|
1782
|
+
var header = "| ".concat(display.columns.join(' | '), " |");
|
|
1783
|
+
var separator = "| ".concat(display.columns.map(function () { return '---'; }).join(' | '), " |");
|
|
1784
|
+
var rows = (display.rows || []).map(function (row) {
|
|
1785
|
+
var cells = display.columns.map(function (column) { return escapeMarkdownCell(row === null || row === void 0 ? void 0 : row[column]); });
|
|
1786
|
+
return "| ".concat(cells.join(' | '), " |");
|
|
1787
|
+
});
|
|
1788
|
+
return __spreadArray([header, separator], __read(rows), false).join('\n').trim();
|
|
1789
|
+
}
|
|
1790
|
+
function escapeMarkdownCell(value) {
|
|
1791
|
+
var raw = value === null || value === undefined ? '' : String(value);
|
|
1792
|
+
return raw.replace(/\|/g, '\\|').replace(/\r?\n/g, ' ').trim();
|
|
1793
|
+
}
|
|
1794
|
+
function isEmptyDisplayValue(value) {
|
|
1795
|
+
if (value === null || value === undefined) {
|
|
1796
|
+
return true;
|
|
1797
|
+
}
|
|
1798
|
+
if (typeof value === 'string') {
|
|
1799
|
+
return !value.trim();
|
|
1800
|
+
}
|
|
1801
|
+
if (Array.isArray(value)) {
|
|
1802
|
+
return value.length === 0;
|
|
1803
|
+
}
|
|
1804
|
+
return false;
|
|
1805
|
+
}
|
|
1806
|
+
function isDisplayObjectLike(value) {
|
|
1807
|
+
if (value === null || value === undefined) {
|
|
1808
|
+
return false;
|
|
1809
|
+
}
|
|
1810
|
+
if (value instanceof Date) {
|
|
1811
|
+
return false;
|
|
1812
|
+
}
|
|
1813
|
+
if (isMongoObjectId(value)) {
|
|
1814
|
+
return false;
|
|
1815
|
+
}
|
|
1816
|
+
return typeof value === 'object';
|
|
1817
|
+
}
|
|
1074
1818
|
function ensureAssistantReadAccess(context, permissionView, collection) {
|
|
1075
1819
|
return __awaiter(this, void 0, void 0, function () {
|
|
1076
1820
|
var idUser, user, isSuperAdmin, normalizedPermission, normalizedCollection;
|
|
@@ -1131,7 +1875,7 @@ function resolveAssistantDatabaseName(database, mongoConfig) {
|
|
|
1131
1875
|
}
|
|
1132
1876
|
function normalizeAssistantFindOptions(options) {
|
|
1133
1877
|
var normalized = options || {};
|
|
1134
|
-
var projection =
|
|
1878
|
+
var projection = sanitizeAssistantProjection(normalized.projection);
|
|
1135
1879
|
var sort = normalized.sort && Object.keys(normalized.sort).length ? normalized.sort : undefined;
|
|
1136
1880
|
var limit = typeof normalized.limit === 'number'
|
|
1137
1881
|
? Math.min(Math.max(normalized.limit, 0), AI_ASSISTANT_MONGO_MAX_LIMIT)
|
|
@@ -1147,6 +1891,33 @@ function normalizeAssistantFindOptions(options) {
|
|
|
1147
1891
|
includeTotal: normalized.includeTotal === true
|
|
1148
1892
|
};
|
|
1149
1893
|
}
|
|
1894
|
+
function sanitizeAssistantProjection(projection) {
|
|
1895
|
+
if (!projection || typeof projection !== 'object') {
|
|
1896
|
+
return undefined;
|
|
1897
|
+
}
|
|
1898
|
+
var keys = Object.keys(projection);
|
|
1899
|
+
if (!keys.length) {
|
|
1900
|
+
return undefined;
|
|
1901
|
+
}
|
|
1902
|
+
var hasInclude = false;
|
|
1903
|
+
var hasExclude = false;
|
|
1904
|
+
keys.forEach(function (key) {
|
|
1905
|
+
var value = projection[key];
|
|
1906
|
+
if (value === 0 || value === false) {
|
|
1907
|
+
hasExclude = true;
|
|
1908
|
+
}
|
|
1909
|
+
else if (value === 1 || value === true) {
|
|
1910
|
+
hasInclude = true;
|
|
1911
|
+
}
|
|
1912
|
+
});
|
|
1913
|
+
if (hasInclude && !hasExclude) {
|
|
1914
|
+
var onlyIds = keys.every(function (key) { return isAssistantIdField(key); });
|
|
1915
|
+
if (onlyIds) {
|
|
1916
|
+
return undefined;
|
|
1917
|
+
}
|
|
1918
|
+
}
|
|
1919
|
+
return projection;
|
|
1920
|
+
}
|
|
1150
1921
|
function normalizeAssistantAggregatePipeline(pipeline) {
|
|
1151
1922
|
if (!Array.isArray(pipeline)) {
|
|
1152
1923
|
return [];
|
|
@@ -1635,7 +2406,7 @@ var CodexWorkerBootstrapError = /** @class */ (function (_super) {
|
|
|
1635
2406
|
}(Error));
|
|
1636
2407
|
function runCodexInWorkerThread(prompt, runOptions, config) {
|
|
1637
2408
|
return __awaiter(this, void 0, void 0, function () {
|
|
1638
|
-
var codexClient, workerPath, codexClient,
|
|
2409
|
+
var codexClient, workerPath, codexClient, error_3, codexClient;
|
|
1639
2410
|
return __generator(this, function (_a) {
|
|
1640
2411
|
switch (_a.label) {
|
|
1641
2412
|
case 0:
|
|
@@ -1655,11 +2426,11 @@ function runCodexInWorkerThread(prompt, runOptions, config) {
|
|
|
1655
2426
|
return [4 /*yield*/, runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config)];
|
|
1656
2427
|
case 6: return [2 /*return*/, _a.sent()];
|
|
1657
2428
|
case 7:
|
|
1658
|
-
|
|
1659
|
-
if (!(
|
|
1660
|
-
throw
|
|
2429
|
+
error_3 = _a.sent();
|
|
2430
|
+
if (!(error_3 instanceof CodexWorkerBootstrapError)) {
|
|
2431
|
+
throw error_3;
|
|
1661
2432
|
}
|
|
1662
|
-
console.error('Codex worker bootstrap failed, falling back to in-process run.',
|
|
2433
|
+
console.error('Codex worker bootstrap failed, falling back to in-process run.', error_3);
|
|
1663
2434
|
codexClient = getAssistantCodexClient();
|
|
1664
2435
|
return [4 /*yield*/, codexClient.run(prompt, runOptions)];
|
|
1665
2436
|
case 8: return [2 /*return*/, _a.sent()];
|
|
@@ -1696,7 +2467,7 @@ function runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config)
|
|
|
1696
2467
|
timeoutMs = ((sanitizedOptions === null || sanitizedOptions === void 0 ? void 0 : sanitizedOptions.timeoutMs) || resolveCodexTimeoutMs()) + 15000;
|
|
1697
2468
|
timeoutController = new AbortController();
|
|
1698
2469
|
timeoutPromise = (function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1699
|
-
var
|
|
2470
|
+
var error_4;
|
|
1700
2471
|
return __generator(this, function (_a) {
|
|
1701
2472
|
switch (_a.label) {
|
|
1702
2473
|
case 0:
|
|
@@ -1706,11 +2477,11 @@ function runCodexInWorkerThreadInternal(workerPath, prompt, runOptions, config)
|
|
|
1706
2477
|
_a.sent();
|
|
1707
2478
|
return [2 /*return*/, { type: 'timeout' }];
|
|
1708
2479
|
case 2:
|
|
1709
|
-
|
|
1710
|
-
if ((
|
|
2480
|
+
error_4 = _a.sent();
|
|
2481
|
+
if ((error_4 === null || error_4 === void 0 ? void 0 : error_4.name) === 'AbortError') {
|
|
1711
2482
|
return [2 /*return*/, { type: 'aborted' }];
|
|
1712
2483
|
}
|
|
1713
|
-
throw
|
|
2484
|
+
throw error_4;
|
|
1714
2485
|
case 3: return [2 /*return*/];
|
|
1715
2486
|
}
|
|
1716
2487
|
});
|
|
@@ -2068,7 +2839,7 @@ function sanitizeAssistantResponse(value) {
|
|
|
2068
2839
|
if (!raw) {
|
|
2069
2840
|
return 'I could not generate a response. Please try again.';
|
|
2070
2841
|
}
|
|
2071
|
-
var withoutBlocks = raw.replace(/```[
|
|
2842
|
+
var withoutBlocks = raw.replace(/```[\s\S]*?```/g, '').replace(/`([^`]+)`/g, '$1').trim();
|
|
2072
2843
|
var stripEstimated = function (line) { return line.replace(/\bEstimated (human )?hours:\s*.*$/i, '').trimEnd(); };
|
|
2073
2844
|
var isTentativeQueryLine = function (line) {
|
|
2074
2845
|
var normalized = line.trim().replace(/^[-*•]+\s*/, '');
|