@resolveio/server-lib 22.1.32 → 22.2.0
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/collections/ai-terminal-message.collection.js +8 -0
- package/collections/ai-terminal-message.collection.js.map +1 -1
- package/fixtures/cron-jobs.js +21 -12
- package/fixtures/cron-jobs.js.map +1 -1
- package/managers/worker-dispatcher.manager.js +2 -2
- package/managers/worker-dispatcher.manager.js.map +1 -1
- package/methods/ai-terminal.d.ts +7 -0
- package/methods/ai-terminal.js +591 -307
- package/methods/ai-terminal.js.map +1 -1
- package/methods/cron-jobs.js +14 -4
- package/methods/cron-jobs.js.map +1 -1
- package/methods/mongo-explorer.js +73 -56
- package/methods/mongo-explorer.js.map +1 -1
- package/methods/report-builder.js +1 -1
- package/methods/report-builder.js.map +1 -1
- package/package.json +1 -1
- package/server-app.js +2 -2
- package/server-app.js.map +1 -1
- package/services/codex-client.js +15 -15
- package/services/codex-client.js.map +1 -1
- package/services/openai-client.js +8 -5
- package/services/openai-client.js.map +1 -1
- package/workers/codex-runner.worker.js +1 -1
- package/workers/codex-runner.worker.js.map +1 -1
|
@@ -88,8 +88,9 @@ var simpl_schema_1 = require("simpl-schema");
|
|
|
88
88
|
var user_collection_1 = require("../collections/user.collection");
|
|
89
89
|
var openai_usage_ledger_manager_1 = require("../managers/openai-usage-ledger.manager");
|
|
90
90
|
var resolveio_server_app_1 = require("../resolveio-server-app");
|
|
91
|
-
var
|
|
91
|
+
var codex_client_1 = require("../services/codex-client");
|
|
92
92
|
var common_1 = require("../util/common");
|
|
93
|
+
var tokenizer_1 = require("../util/tokenizer");
|
|
93
94
|
var DEFAULT_LIMIT = 100;
|
|
94
95
|
var MAX_LIMIT = 2000;
|
|
95
96
|
var ISO_DATE_REGEX = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(?:\.\d+)?Z$/;
|
|
@@ -729,7 +730,7 @@ function normalizeRiskReview(operation, payload, model, requestId) {
|
|
|
729
730
|
? Math.max(0, Math.min(1, normalizedConfidence))
|
|
730
731
|
: 0.6;
|
|
731
732
|
var summary = normalizeOptionalString(payload === null || payload === void 0 ? void 0 : payload.summary)
|
|
732
|
-
|| "
|
|
733
|
+
|| "AI review marked this operation as ".concat(riskLevel, " risk.");
|
|
733
734
|
var reasons = normalizeRiskList(payload === null || payload === void 0 ? void 0 : payload.reasons);
|
|
734
735
|
var suggestedChecks = normalizeRiskList(payload === null || payload === void 0 ? void 0 : payload.suggested_checks);
|
|
735
736
|
var shouldBlock = (payload === null || payload === void 0 ? void 0 : payload.should_block) === true || riskLevel === 'critical';
|
|
@@ -783,6 +784,26 @@ function resolveRiskReviewSettings() {
|
|
|
783
784
|
retryDelayMs: retryDelayMs
|
|
784
785
|
};
|
|
785
786
|
}
|
|
787
|
+
function buildCodexPrompt(systemPrompt, userPrompt) {
|
|
788
|
+
return "System:\n".concat(systemPrompt, "\n\nUser:\n").concat(userPrompt).trim();
|
|
789
|
+
}
|
|
790
|
+
function buildCodexClient(settings) {
|
|
791
|
+
var fallbackModels = [];
|
|
792
|
+
var fallback = normalizeOptionalString(settings.fallbackModel);
|
|
793
|
+
if (fallback && fallback !== settings.model) {
|
|
794
|
+
fallbackModels.push(fallback);
|
|
795
|
+
}
|
|
796
|
+
return new codex_client_1.CodexClient(__assign(__assign({ apiKey: settings.apiKey, baseUrl: settings.baseUrl, model: settings.model }, (fallbackModels.length ? { fallbackModel: fallbackModels[0], fallbackModels: fallbackModels } : {})), { maxRetries: (0, common_1.round)(settings.maxRetries || 0), retryDelayMs: (0, common_1.round)(settings.retryDelayMs || 0) }));
|
|
797
|
+
}
|
|
798
|
+
function estimateCodexUsage(messages, responseText, model) {
|
|
799
|
+
var inputTokens = (0, tokenizer_1.countChatTokens)(messages, model);
|
|
800
|
+
var outputTokens = (0, tokenizer_1.countTokens)(responseText || '', model);
|
|
801
|
+
return {
|
|
802
|
+
inputTokens: inputTokens,
|
|
803
|
+
outputTokens: outputTokens,
|
|
804
|
+
totalTokens: inputTokens + outputTokens
|
|
805
|
+
};
|
|
806
|
+
}
|
|
786
807
|
function buildRiskReviewPrompt(input) {
|
|
787
808
|
var payload = {
|
|
788
809
|
database: input.database,
|
|
@@ -803,7 +824,7 @@ function buildRiskReviewPrompt(input) {
|
|
|
803
824
|
}
|
|
804
825
|
function reviewOperationRisk(input) {
|
|
805
826
|
return __awaiter(this, void 0, void 0, function () {
|
|
806
|
-
var settings, client, systemPrompt,
|
|
827
|
+
var settings, client, systemPrompt, userPrompt, prompt, responseText, payload, err_1, detail;
|
|
807
828
|
return __generator(this, function (_a) {
|
|
808
829
|
switch (_a.label) {
|
|
809
830
|
case 0:
|
|
@@ -812,19 +833,9 @@ function reviewOperationRisk(input) {
|
|
|
812
833
|
return [2 /*return*/, buildDisabledRiskReview(input.operation)];
|
|
813
834
|
}
|
|
814
835
|
if (!settings.apiKey) {
|
|
815
|
-
return [2 /*return*/, buildFallbackRiskReview(input.operation, 'AI risk review unavailable:
|
|
836
|
+
return [2 /*return*/, buildFallbackRiskReview(input.operation, 'AI risk review unavailable: AI API key is missing.')];
|
|
816
837
|
}
|
|
817
|
-
client =
|
|
818
|
-
apiKey: settings.apiKey,
|
|
819
|
-
baseUrl: settings.baseUrl,
|
|
820
|
-
model: settings.model,
|
|
821
|
-
fallbackModel: settings.fallbackModel,
|
|
822
|
-
temperature: 0.1,
|
|
823
|
-
maxTokens: settings.maxTokens,
|
|
824
|
-
maxRetries: (0, common_1.round)(settings.maxRetries),
|
|
825
|
-
retryDelayMs: (0, common_1.round)(settings.retryDelayMs),
|
|
826
|
-
responseFormat: 'json'
|
|
827
|
-
});
|
|
838
|
+
client = buildCodexClient(settings);
|
|
828
839
|
systemPrompt = [
|
|
829
840
|
'You are a MongoDB operation safety reviewer for a production SaaS application.',
|
|
830
841
|
'Respond with a single JSON object only.',
|
|
@@ -837,20 +848,27 @@ function reviewOperationRisk(input) {
|
|
|
837
848
|
'confidence (number between 0 and 1).',
|
|
838
849
|
'Keep summary concise (<= 220 chars).'
|
|
839
850
|
].join(' ');
|
|
851
|
+
userPrompt = buildRiskReviewPrompt(input);
|
|
852
|
+
prompt = buildCodexPrompt(systemPrompt, userPrompt);
|
|
840
853
|
_a.label = 1;
|
|
841
854
|
case 1:
|
|
842
855
|
_a.trys.push([1, 3, , 4]);
|
|
843
|
-
return [4 /*yield*/, client.
|
|
844
|
-
{ role: 'system', content: systemPrompt },
|
|
845
|
-
{ role: 'user', content: buildRiskReviewPrompt(input) }
|
|
846
|
-
], {
|
|
856
|
+
return [4 /*yield*/, client.run(prompt, {
|
|
847
857
|
timeoutMs: (0, common_1.round)(settings.timeoutMs),
|
|
848
|
-
|
|
858
|
+
threadOptions: {
|
|
859
|
+
model: settings.model,
|
|
860
|
+
sandboxMode: 'read-only',
|
|
861
|
+
skipGitRepoCheck: true,
|
|
862
|
+
networkAccessEnabled: false,
|
|
863
|
+
webSearchMode: 'disabled',
|
|
864
|
+
webSearchEnabled: false,
|
|
865
|
+
approvalPolicy: 'never'
|
|
866
|
+
}
|
|
849
867
|
})];
|
|
850
868
|
case 2:
|
|
851
|
-
|
|
852
|
-
payload = parseRiskReviewPayload(
|
|
853
|
-
return [2 /*return*/, normalizeRiskReview(input.operation, payload,
|
|
869
|
+
responseText = _a.sent();
|
|
870
|
+
payload = parseRiskReviewPayload(responseText);
|
|
871
|
+
return [2 /*return*/, normalizeRiskReview(input.operation, payload, settings.model, '')];
|
|
854
872
|
case 3:
|
|
855
873
|
err_1 = _a.sent();
|
|
856
874
|
detail = (err_1 === null || err_1 === void 0 ? void 0 : err_1.message) ? String(err_1.message) : 'Unknown AI review error';
|
|
@@ -1147,7 +1165,7 @@ function resolveUsageClientId(idClientInput, idUser) {
|
|
|
1147
1165
|
}
|
|
1148
1166
|
function executeMongoExplorerAi(payload, context) {
|
|
1149
1167
|
return __awaiter(this, void 0, void 0, function () {
|
|
1150
|
-
var input, prompt, database, db, availableCollections, listed, selectedCollection, availableFields, settings, maxResults, client,
|
|
1168
|
+
var input, prompt, database, db, availableCollections, listed, selectedCollection, availableFields, settings, maxResults, client, messages, responseText, parsed, action, collection, plan, removedRestrictedStages, optionsRaw, aggregateLimit, pipelineResult, aggregateOptions, aggregateRows, rows, query, options, findOptions, rows, total, _a, usage, idClient;
|
|
1151
1169
|
var _b;
|
|
1152
1170
|
return __generator(this, function (_c) {
|
|
1153
1171
|
switch (_c.label) {
|
|
@@ -1180,39 +1198,38 @@ function executeMongoExplorerAi(payload, context) {
|
|
|
1180
1198
|
}
|
|
1181
1199
|
settings = resolveMongoExplorerAiSettings();
|
|
1182
1200
|
if (!settings.apiKey) {
|
|
1183
|
-
throw new Error('
|
|
1201
|
+
throw new Error('AI API key missing. Add an AI API key to server config.');
|
|
1184
1202
|
}
|
|
1185
1203
|
maxResults = normalizeAiResultLimit(input.max_results, 100);
|
|
1186
|
-
client =
|
|
1187
|
-
|
|
1188
|
-
|
|
1189
|
-
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
content: buildMongoExplorerAiUserPrompt({
|
|
1202
|
-
prompt: prompt,
|
|
1203
|
-
selectedCollection: selectedCollection,
|
|
1204
|
-
availableCollections: availableCollections,
|
|
1205
|
-
availableFields: availableFields,
|
|
1206
|
-
maxResults: maxResults
|
|
1207
|
-
})
|
|
1208
|
-
}
|
|
1209
|
-
], {
|
|
1204
|
+
client = buildCodexClient(settings);
|
|
1205
|
+
messages = [
|
|
1206
|
+
{ role: 'system', content: buildMongoExplorerAiSystemPrompt() },
|
|
1207
|
+
{
|
|
1208
|
+
role: 'user',
|
|
1209
|
+
content: buildMongoExplorerAiUserPrompt({
|
|
1210
|
+
prompt: prompt,
|
|
1211
|
+
selectedCollection: selectedCollection,
|
|
1212
|
+
availableCollections: availableCollections,
|
|
1213
|
+
availableFields: availableFields,
|
|
1214
|
+
maxResults: maxResults
|
|
1215
|
+
})
|
|
1216
|
+
}
|
|
1217
|
+
];
|
|
1218
|
+
return [4 /*yield*/, client.run(buildCodexPrompt(messages[0].content, messages[1].content), {
|
|
1210
1219
|
timeoutMs: (0, common_1.round)(settings.timeoutMs),
|
|
1211
|
-
|
|
1220
|
+
threadOptions: {
|
|
1221
|
+
model: settings.model,
|
|
1222
|
+
sandboxMode: 'read-only',
|
|
1223
|
+
skipGitRepoCheck: true,
|
|
1224
|
+
networkAccessEnabled: false,
|
|
1225
|
+
webSearchMode: 'disabled',
|
|
1226
|
+
webSearchEnabled: false,
|
|
1227
|
+
approvalPolicy: 'never'
|
|
1228
|
+
}
|
|
1212
1229
|
})];
|
|
1213
1230
|
case 3:
|
|
1214
|
-
|
|
1215
|
-
parsed = parseAiPlanPayload(
|
|
1231
|
+
responseText = _c.sent();
|
|
1232
|
+
parsed = parseAiPlanPayload(responseText);
|
|
1216
1233
|
action = normalizeAiAction((parsed === null || parsed === void 0 ? void 0 : parsed.action) || (Array.isArray(parsed === null || parsed === void 0 ? void 0 : parsed.pipeline) ? 'aggregate' : 'find'));
|
|
1217
1234
|
collection = resolveCollectionFromList((parsed === null || parsed === void 0 ? void 0 : parsed.collection) || (parsed === null || parsed === void 0 ? void 0 : parsed.collection_name), availableCollections, selectedCollection || availableCollections[0]);
|
|
1218
1235
|
if (!collection) {
|
|
@@ -1285,19 +1302,19 @@ function executeMongoExplorerAi(payload, context) {
|
|
|
1285
1302
|
_c.label = 10;
|
|
1286
1303
|
case 10:
|
|
1287
1304
|
plan.notes = buildMongoExplorerAiNotes(parsed === null || parsed === void 0 ? void 0 : parsed.notes, plan.action, plan.collection, Array.isArray(plan.documents) ? plan.documents.length : 0, typeof plan.total === 'number' ? plan.total : null, removedRestrictedStages);
|
|
1288
|
-
usage =
|
|
1305
|
+
usage = estimateCodexUsage(messages, responseText, settings.model);
|
|
1289
1306
|
return [4 /*yield*/, resolveUsageClientId(input.id_client, context === null || context === void 0 ? void 0 : context.id_user)];
|
|
1290
1307
|
case 11:
|
|
1291
1308
|
idClient = _c.sent();
|
|
1292
1309
|
if (!(idClient && usage.totalTokens)) return [3 /*break*/, 13];
|
|
1293
1310
|
return [4 /*yield*/, (0, openai_usage_ledger_manager_1.recordOpenAIUsage)({
|
|
1294
1311
|
id_client: idClient,
|
|
1295
|
-
model:
|
|
1312
|
+
model: settings.model || 'unknown',
|
|
1296
1313
|
input_tokens: usage.inputTokens || 0,
|
|
1297
1314
|
output_tokens: usage.outputTokens || 0,
|
|
1298
1315
|
total_tokens: usage.totalTokens || 0,
|
|
1299
1316
|
category: 'mongo-explorer-ai',
|
|
1300
|
-
id_request:
|
|
1317
|
+
id_request: ''
|
|
1301
1318
|
})];
|
|
1302
1319
|
case 12:
|
|
1303
1320
|
_c.sent();
|
|
@@ -1305,7 +1322,7 @@ function executeMongoExplorerAi(payload, context) {
|
|
|
1305
1322
|
case 13: return [2 /*return*/, {
|
|
1306
1323
|
notes: plan.notes,
|
|
1307
1324
|
plan: plan,
|
|
1308
|
-
model:
|
|
1325
|
+
model: settings.model,
|
|
1309
1326
|
usage: {
|
|
1310
1327
|
input_tokens: usage.inputTokens || 0,
|
|
1311
1328
|
output_tokens: usage.outputTokens || 0,
|