@resolveio/server-lib 22.1.0 → 22.1.1
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/methods/ai-terminal.d.ts +9 -0
- package/methods/ai-terminal.js +479 -162
- package/methods/ai-terminal.js.map +1 -1
- package/package.json +4 -2
package/methods/ai-terminal.js
CHANGED
|
@@ -109,18 +109,21 @@ exports.loadAiTerminalMethods = loadAiTerminalMethods;
|
|
|
109
109
|
exports.executeAiAssistantMongoRead = executeAiAssistantMongoRead;
|
|
110
110
|
exports.executeAiAssistantMongoAggregate = executeAiAssistantMongoAggregate;
|
|
111
111
|
exports.extractAssistantMongoDirective = extractAssistantMongoDirective;
|
|
112
|
+
exports.buildAssistantInvoiceCustomerLabelExpr = buildAssistantInvoiceCustomerLabelExpr;
|
|
112
113
|
exports.buildAssistantDatedPivotDisplay = buildAssistantDatedPivotDisplay;
|
|
113
114
|
exports.normalizeIdsForTargetField = normalizeIdsForTargetField;
|
|
114
115
|
exports.serializeMongoValue = serializeMongoValue;
|
|
115
116
|
exports.flattenForTable = flattenForTable;
|
|
116
117
|
exports.buildDisplayTable = buildDisplayTable;
|
|
117
118
|
exports.formatDisplayTableMarkdown = formatDisplayTableMarkdown;
|
|
119
|
+
exports.resolveAssistantReadDisplayMaxRows = resolveAssistantReadDisplayMaxRows;
|
|
118
120
|
exports.normalizeAssistantNowExprPlaceholders = normalizeAssistantNowExprPlaceholders;
|
|
119
121
|
exports.rewriteMatchExpressionsToExpr = rewriteMatchExpressionsToExpr;
|
|
120
122
|
exports.normalizeAssistantMonthlyCalendarWindowPipeline = normalizeAssistantMonthlyCalendarWindowPipeline;
|
|
121
123
|
exports.stripQueryFieldPathsDeep = stripQueryFieldPathsDeep;
|
|
122
124
|
exports.stripScopedFieldsFromPipeline = stripScopedFieldsFromPipeline;
|
|
123
125
|
exports.rewriteEmbeddedMatchObjects = rewriteEmbeddedMatchObjects;
|
|
126
|
+
exports.resolveAssistantCollectionOverride = resolveAssistantCollectionOverride;
|
|
124
127
|
exports.collectUserViewPermissions = collectUserViewPermissions;
|
|
125
128
|
exports.userHasInvoiceAccess = userHasInvoiceAccess;
|
|
126
129
|
exports.resolveAssistantUserAccessTier = resolveAssistantUserAccessTier;
|
|
@@ -389,6 +392,11 @@ var AI_ASSISTANT_TERM_SYNONYMS = [
|
|
|
389
392
|
pattern: /\btruck\s+treating\s+jobs?\b/i,
|
|
390
393
|
expansions: ['truck treating deliveries', 'truck-treating-deliveries', 'truck treating route events']
|
|
391
394
|
},
|
|
395
|
+
{
|
|
396
|
+
label: 'active clients',
|
|
397
|
+
pattern: /\b(?:how\s+many\s+)?active\s+(?:clients?|customers?)\b/i,
|
|
398
|
+
expansions: ['customers', 'clients', 'customer status', 'client status']
|
|
399
|
+
},
|
|
392
400
|
{
|
|
393
401
|
label: 'blend tickets',
|
|
394
402
|
pattern: /\bblend(?:ing)?\s+tickets?\b/i,
|
|
@@ -2318,10 +2326,10 @@ function executeAiAssistantReportBuilderAggregate(payload, context) {
|
|
|
2318
2326
|
}
|
|
2319
2327
|
function executeAiAssistantMongoRead(payload, context) {
|
|
2320
2328
|
return __awaiter(this, void 0, void 0, function () {
|
|
2321
|
-
var input, rawCollection, dbName, db, collectionResolution, collection, bridgeCollection, schemaFields, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, strippedClient, clientScopedQuery, scopedQuery, normalized, findOptions, documents, executedQuery, probeDocs, dateFallback, fallbackQuery, fallbackDocs, expanded, fallbackDocs, nameFallback, fallbackDocs, _c, chemicalLookup, fallbackDocs, queryFields, _d, aliases, rewrittenQuery, fallbackDocs, _e, idLookup, fallbackDocs, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, nameFields, dateFields, diagnostics, queryNoName,
|
|
2322
|
-
var
|
|
2323
|
-
return __generator(this, function (
|
|
2324
|
-
switch (
|
|
2329
|
+
var input, rawCollection, dbName, db, collectionResolution, collection, bridgeCollection, schemaFields, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, strippedClient, clientScopedQuery, scopedQuery, normalized, findOptions, documents, executedQuery, probeDocs, dateFallback, fallbackQuery, fallbackDocs, expanded, fallbackDocs, nameFallback, fallbackDocs, _c, chemicalLookup, fallbackDocs, queryFields, _d, aliases, rewrittenQuery, fallbackDocs, _e, activeFallback, fallbackDocs, _f, idLookup, fallbackDocs, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, nameFields, dateFields, diagnostics, queryNoName, _g, queryNoDate, _h, _j, _k, _l, allCollections, base, alt, altCount, _m, total, sanitizedDocuments, requestedFields, missingFields, _o, projectionAliases, expandedProjection, refreshedDocs, includeIds, fieldAliases, displayDocs, idLookupDisplay, priorityFields, displayMaxRows, display;
|
|
2330
|
+
var _p, _q;
|
|
2331
|
+
return __generator(this, function (_r) {
|
|
2332
|
+
switch (_r.label) {
|
|
2325
2333
|
case 0:
|
|
2326
2334
|
input = payload || {};
|
|
2327
2335
|
rawCollection = normalizeOptionalString(input.collection);
|
|
@@ -2332,22 +2340,22 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2332
2340
|
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
2333
2341
|
return [4 /*yield*/, resolveAssistantCollectionName(db, dbName, rawCollection)];
|
|
2334
2342
|
case 1:
|
|
2335
|
-
collectionResolution =
|
|
2343
|
+
collectionResolution = _r.sent();
|
|
2336
2344
|
collection = collectionResolution.name || rawCollection;
|
|
2337
2345
|
return [4 /*yield*/, resolveAssistantReportBuilderBridgeCollection(collection, db, dbName)];
|
|
2338
2346
|
case 2:
|
|
2339
|
-
bridgeCollection =
|
|
2347
|
+
bridgeCollection = _r.sent();
|
|
2340
2348
|
if (bridgeCollection.fallbackFrom) {
|
|
2341
2349
|
collection = bridgeCollection.collection;
|
|
2342
2350
|
}
|
|
2343
2351
|
schemaFields = getCollectionSchemaFieldNames(collection);
|
|
2344
2352
|
return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
|
|
2345
2353
|
case 3:
|
|
2346
|
-
_a =
|
|
2354
|
+
_a = _r.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
|
|
2347
2355
|
if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
|
|
2348
2356
|
throw new Error('AI assistant report builder bridge: Access denied.');
|
|
2349
2357
|
}
|
|
2350
|
-
customerId = normalizeOptionalString((
|
|
2358
|
+
customerId = normalizeOptionalString((_p = user === null || user === void 0 ? void 0 : user.other) === null || _p === void 0 ? void 0 : _p.id_customer);
|
|
2351
2359
|
fallbackMeta = {};
|
|
2352
2360
|
if (bridgeCollection.fallbackFrom) {
|
|
2353
2361
|
fallbackMeta.reportBuilderBridge = {
|
|
@@ -2379,11 +2387,11 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2379
2387
|
if (!(!isSuperAdmin && normalizedClient)) return [3 /*break*/, 5];
|
|
2380
2388
|
return [4 /*yield*/, collectionHasClientIndex(db, dbName, collection)];
|
|
2381
2389
|
case 4:
|
|
2382
|
-
_b =
|
|
2390
|
+
_b = _r.sent();
|
|
2383
2391
|
return [3 /*break*/, 6];
|
|
2384
2392
|
case 5:
|
|
2385
2393
|
_b = false;
|
|
2386
|
-
|
|
2394
|
+
_r.label = 6;
|
|
2387
2395
|
case 6:
|
|
2388
2396
|
shouldScopeByClient = _b;
|
|
2389
2397
|
if (!isSuperAdmin && shouldScopeByClient) {
|
|
@@ -2403,7 +2411,7 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2403
2411
|
findOptions = __assign(__assign({}, normalized.findOptions), { readPreference: AI_ASSISTANT_READ_PREFERENCE });
|
|
2404
2412
|
return [4 /*yield*/, db.collection(collection).find(scopedQuery, findOptions).toArray()];
|
|
2405
2413
|
case 7:
|
|
2406
|
-
documents =
|
|
2414
|
+
documents = _r.sent();
|
|
2407
2415
|
executedQuery = scopedQuery;
|
|
2408
2416
|
probeDocs = null;
|
|
2409
2417
|
if (!!documents.length) return [3 /*break*/, 9];
|
|
@@ -2413,13 +2421,13 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2413
2421
|
fallbackMeta.dateField = __assign(__assign({}, dateFallback), { attempted: true, used: false });
|
|
2414
2422
|
return [4 /*yield*/, db.collection(collection).find(fallbackQuery, findOptions).toArray()];
|
|
2415
2423
|
case 8:
|
|
2416
|
-
fallbackDocs =
|
|
2424
|
+
fallbackDocs = _r.sent();
|
|
2417
2425
|
if (fallbackDocs.length) {
|
|
2418
2426
|
documents = fallbackDocs;
|
|
2419
2427
|
executedQuery = fallbackQuery;
|
|
2420
2428
|
fallbackMeta.dateField.used = true;
|
|
2421
2429
|
}
|
|
2422
|
-
|
|
2430
|
+
_r.label = 9;
|
|
2423
2431
|
case 9:
|
|
2424
2432
|
if (!!documents.length) return [3 /*break*/, 11];
|
|
2425
2433
|
expanded = expandQueryDateFallbacks(executedQuery, schemaFields);
|
|
@@ -2431,13 +2439,13 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2431
2439
|
};
|
|
2432
2440
|
return [4 /*yield*/, db.collection(collection).find(expanded.query, findOptions).toArray()];
|
|
2433
2441
|
case 10:
|
|
2434
|
-
fallbackDocs =
|
|
2442
|
+
fallbackDocs = _r.sent();
|
|
2435
2443
|
if (fallbackDocs.length) {
|
|
2436
2444
|
documents = fallbackDocs;
|
|
2437
2445
|
executedQuery = expanded.query;
|
|
2438
2446
|
fallbackMeta.dateFieldsExpanded.used = true;
|
|
2439
2447
|
}
|
|
2440
|
-
|
|
2448
|
+
_r.label = 11;
|
|
2441
2449
|
case 11:
|
|
2442
2450
|
if (!!documents.length) return [3 /*break*/, 13];
|
|
2443
2451
|
nameFallback = resolveReadNameMatchFallback(executedQuery);
|
|
@@ -2450,13 +2458,13 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2450
2458
|
};
|
|
2451
2459
|
return [4 /*yield*/, db.collection(collection).find(nameFallback.query, findOptions).toArray()];
|
|
2452
2460
|
case 12:
|
|
2453
|
-
fallbackDocs =
|
|
2461
|
+
fallbackDocs = _r.sent();
|
|
2454
2462
|
if (fallbackDocs.length) {
|
|
2455
2463
|
documents = fallbackDocs;
|
|
2456
2464
|
executedQuery = nameFallback.query;
|
|
2457
2465
|
fallbackMeta.nameMatch.used = true;
|
|
2458
2466
|
}
|
|
2459
|
-
|
|
2467
|
+
_r.label = 13;
|
|
2460
2468
|
case 13:
|
|
2461
2469
|
if (!!documents.length) return [3 /*break*/, 18];
|
|
2462
2470
|
_c = probeDocs;
|
|
@@ -2470,8 +2478,8 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2470
2478
|
includeClientScope: shouldScopeByClient
|
|
2471
2479
|
})];
|
|
2472
2480
|
case 14:
|
|
2473
|
-
_c = (
|
|
2474
|
-
|
|
2481
|
+
_c = (_r.sent());
|
|
2482
|
+
_r.label = 15;
|
|
2475
2483
|
case 15:
|
|
2476
2484
|
probeDocs = _c;
|
|
2477
2485
|
return [4 /*yield*/, applyChemicalNameLookupFallbackToQuery({
|
|
@@ -2484,18 +2492,18 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2484
2492
|
probeDocs: probeDocs || undefined
|
|
2485
2493
|
})];
|
|
2486
2494
|
case 16:
|
|
2487
|
-
chemicalLookup =
|
|
2495
|
+
chemicalLookup = _r.sent();
|
|
2488
2496
|
if (!chemicalLookup) return [3 /*break*/, 18];
|
|
2489
2497
|
fallbackMeta.chemicalLookup = __assign(__assign({}, chemicalLookup.meta), { attempted: true, used: false });
|
|
2490
2498
|
return [4 /*yield*/, db.collection(collection).find(chemicalLookup.query, findOptions).toArray()];
|
|
2491
2499
|
case 17:
|
|
2492
|
-
fallbackDocs =
|
|
2500
|
+
fallbackDocs = _r.sent();
|
|
2493
2501
|
if (fallbackDocs.length) {
|
|
2494
2502
|
documents = fallbackDocs;
|
|
2495
2503
|
executedQuery = chemicalLookup.query;
|
|
2496
2504
|
fallbackMeta.chemicalLookup.used = true;
|
|
2497
2505
|
}
|
|
2498
|
-
|
|
2506
|
+
_r.label = 18;
|
|
2499
2507
|
case 18:
|
|
2500
2508
|
if (!!documents.length) return [3 /*break*/, 22];
|
|
2501
2509
|
queryFields = extractQueryFieldPaths(executedQuery).filter(function (field) { return !isAssistantIdField(field); });
|
|
@@ -2511,8 +2519,8 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2511
2519
|
includeClientScope: shouldScopeByClient
|
|
2512
2520
|
})];
|
|
2513
2521
|
case 19:
|
|
2514
|
-
_d = (
|
|
2515
|
-
|
|
2522
|
+
_d = (_r.sent());
|
|
2523
|
+
_r.label = 20;
|
|
2516
2524
|
case 20:
|
|
2517
2525
|
probeDocs = _d;
|
|
2518
2526
|
if (!probeDocs.length) return [3 /*break*/, 22];
|
|
@@ -2530,15 +2538,15 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2530
2538
|
}, executedQuery);
|
|
2531
2539
|
return [4 /*yield*/, db.collection(collection).find(rewrittenQuery, findOptions).toArray()];
|
|
2532
2540
|
case 21:
|
|
2533
|
-
fallbackDocs =
|
|
2541
|
+
fallbackDocs = _r.sent();
|
|
2534
2542
|
if (fallbackDocs.length) {
|
|
2535
2543
|
documents = fallbackDocs;
|
|
2536
2544
|
executedQuery = rewrittenQuery;
|
|
2537
2545
|
fallbackMeta.queryFieldAliases.used = true;
|
|
2538
2546
|
}
|
|
2539
|
-
|
|
2547
|
+
_r.label = 22;
|
|
2540
2548
|
case 22:
|
|
2541
|
-
if (!!documents.length) return [3 /*break*/,
|
|
2549
|
+
if (!!documents.length) return [3 /*break*/, 26];
|
|
2542
2550
|
_e = probeDocs;
|
|
2543
2551
|
if (_e) return [3 /*break*/, 24];
|
|
2544
2552
|
return [4 /*yield*/, fetchAssistantProbeDocs({
|
|
@@ -2550,10 +2558,44 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2550
2558
|
includeClientScope: shouldScopeByClient
|
|
2551
2559
|
})];
|
|
2552
2560
|
case 23:
|
|
2553
|
-
_e = (
|
|
2554
|
-
|
|
2561
|
+
_e = (_r.sent());
|
|
2562
|
+
_r.label = 24;
|
|
2555
2563
|
case 24:
|
|
2556
2564
|
probeDocs = _e;
|
|
2565
|
+
activeFallback = resolveReadActiveStatusFallback(executedQuery, probeDocs || []);
|
|
2566
|
+
if (!activeFallback) return [3 /*break*/, 26];
|
|
2567
|
+
fallbackMeta.activeStatus = {
|
|
2568
|
+
fields: activeFallback.fields,
|
|
2569
|
+
attempted: true,
|
|
2570
|
+
used: false,
|
|
2571
|
+
reason: 'active_fields_missing_in_collection'
|
|
2572
|
+
};
|
|
2573
|
+
return [4 /*yield*/, db.collection(collection).find(activeFallback.query, findOptions).toArray()];
|
|
2574
|
+
case 25:
|
|
2575
|
+
fallbackDocs = _r.sent();
|
|
2576
|
+
if (fallbackDocs.length) {
|
|
2577
|
+
documents = fallbackDocs;
|
|
2578
|
+
executedQuery = activeFallback.query;
|
|
2579
|
+
fallbackMeta.activeStatus.used = true;
|
|
2580
|
+
}
|
|
2581
|
+
_r.label = 26;
|
|
2582
|
+
case 26:
|
|
2583
|
+
if (!!documents.length) return [3 /*break*/, 31];
|
|
2584
|
+
_f = probeDocs;
|
|
2585
|
+
if (_f) return [3 /*break*/, 28];
|
|
2586
|
+
return [4 /*yield*/, fetchAssistantProbeDocs({
|
|
2587
|
+
db: db,
|
|
2588
|
+
collection: collection,
|
|
2589
|
+
idClient: normalizedClient,
|
|
2590
|
+
idCustomer: customerId,
|
|
2591
|
+
isSuperAdmin: isSuperAdmin,
|
|
2592
|
+
includeClientScope: shouldScopeByClient
|
|
2593
|
+
})];
|
|
2594
|
+
case 27:
|
|
2595
|
+
_f = (_r.sent());
|
|
2596
|
+
_r.label = 28;
|
|
2597
|
+
case 28:
|
|
2598
|
+
probeDocs = _f;
|
|
2557
2599
|
return [4 /*yield*/, applyIdLookupFallbackToQuery({
|
|
2558
2600
|
query: executedQuery,
|
|
2559
2601
|
db: db,
|
|
@@ -2563,29 +2605,29 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2563
2605
|
isSuperAdmin: isSuperAdmin,
|
|
2564
2606
|
probeDocs: probeDocs || undefined
|
|
2565
2607
|
})];
|
|
2566
|
-
case
|
|
2567
|
-
idLookup =
|
|
2568
|
-
if (!idLookup) return [3 /*break*/,
|
|
2608
|
+
case 29:
|
|
2609
|
+
idLookup = _r.sent();
|
|
2610
|
+
if (!idLookup) return [3 /*break*/, 31];
|
|
2569
2611
|
fallbackMeta.idLookup = __assign(__assign({}, idLookup.meta), { attempted: true, used: false });
|
|
2570
2612
|
return [4 /*yield*/, db.collection(collection).find(idLookup.query, findOptions).toArray()];
|
|
2571
|
-
case
|
|
2572
|
-
fallbackDocs =
|
|
2613
|
+
case 30:
|
|
2614
|
+
fallbackDocs = _r.sent();
|
|
2573
2615
|
if (fallbackDocs.length) {
|
|
2574
2616
|
documents = fallbackDocs;
|
|
2575
2617
|
executedQuery = idLookup.query;
|
|
2576
2618
|
fallbackMeta.idLookup.used = true;
|
|
2577
2619
|
}
|
|
2578
|
-
|
|
2579
|
-
case
|
|
2580
|
-
if (!!documents.length) return [3 /*break*/,
|
|
2620
|
+
_r.label = 31;
|
|
2621
|
+
case 31:
|
|
2622
|
+
if (!!documents.length) return [3 /*break*/, 34];
|
|
2581
2623
|
return [4 /*yield*/, resolveBaseCollectionFromReport(db, dbName, collection)];
|
|
2582
|
-
case
|
|
2583
|
-
baseCollection =
|
|
2584
|
-
if (!(baseCollection && baseCollection !== collection)) return [3 /*break*/,
|
|
2624
|
+
case 32:
|
|
2625
|
+
baseCollection = _r.sent();
|
|
2626
|
+
if (!(baseCollection && baseCollection !== collection)) return [3 /*break*/, 34];
|
|
2585
2627
|
fallbackPayload = __assign(__assign({}, input), { collection: baseCollection });
|
|
2586
2628
|
return [4 /*yield*/, executeAiAssistantMongoRead(fallbackPayload, context)];
|
|
2587
|
-
case
|
|
2588
|
-
fallbackResult =
|
|
2629
|
+
case 33:
|
|
2630
|
+
fallbackResult = _r.sent();
|
|
2589
2631
|
if (Array.isArray(fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.documents) && fallbackResult.documents.length) {
|
|
2590
2632
|
if (isSuperAdmin && (fallbackResult === null || fallbackResult === void 0 ? void 0 : fallbackResult.debug) && typeof fallbackResult.debug === 'object') {
|
|
2591
2633
|
existingFallbacks = fallbackResult.debug.fallbacks && typeof fallbackResult.debug.fallbacks === 'object'
|
|
@@ -2602,9 +2644,9 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2602
2644
|
if (isSuperAdmin) {
|
|
2603
2645
|
fallbackMeta.reportFallback = { from: collection, to: baseCollection, attempted: true, used: false };
|
|
2604
2646
|
}
|
|
2605
|
-
|
|
2606
|
-
case
|
|
2607
|
-
if (!(!documents.length && isSuperAdmin)) return [3 /*break*/,
|
|
2647
|
+
_r.label = 34;
|
|
2648
|
+
case 34:
|
|
2649
|
+
if (!(!documents.length && isSuperAdmin)) return [3 /*break*/, 51];
|
|
2608
2650
|
nameFields = collectMatchFieldsByCondition(executedQuery, function (field, condition) { return isRegexMatchCondition(condition)
|
|
2609
2651
|
|| (typeof condition === 'string' && shouldApplyAssistantNameRegex(field)); });
|
|
2610
2652
|
dateFields = collectMatchFieldsByCondition(executedQuery, function (_field, condition) { return isDateCondition(condition); });
|
|
@@ -2612,36 +2654,36 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2612
2654
|
nameFields: nameFields.length ? nameFields : undefined,
|
|
2613
2655
|
dateFields: dateFields.length ? dateFields : undefined
|
|
2614
2656
|
};
|
|
2615
|
-
|
|
2616
|
-
case
|
|
2617
|
-
|
|
2618
|
-
if (!nameFields.length) return [3 /*break*/,
|
|
2657
|
+
_r.label = 35;
|
|
2658
|
+
case 35:
|
|
2659
|
+
_r.trys.push([35, 40, , 41]);
|
|
2660
|
+
if (!nameFields.length) return [3 /*break*/, 37];
|
|
2619
2661
|
queryNoName = stripMatchFields(executedQuery, nameFields);
|
|
2620
|
-
|
|
2662
|
+
_g = diagnostics;
|
|
2621
2663
|
return [4 /*yield*/, db.collection(collection).countDocuments(queryNoName, {
|
|
2622
2664
|
readPreference: AI_ASSISTANT_READ_PREFERENCE
|
|
2623
2665
|
})];
|
|
2624
|
-
case
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
case
|
|
2628
|
-
if (!dateFields.length) return [3 /*break*/,
|
|
2666
|
+
case 36:
|
|
2667
|
+
_g.recentCount = _r.sent();
|
|
2668
|
+
_r.label = 37;
|
|
2669
|
+
case 37:
|
|
2670
|
+
if (!dateFields.length) return [3 /*break*/, 39];
|
|
2629
2671
|
queryNoDate = stripMatchFields(executedQuery, dateFields);
|
|
2630
|
-
|
|
2672
|
+
_h = diagnostics;
|
|
2631
2673
|
return [4 /*yield*/, db.collection(collection).countDocuments(queryNoDate, {
|
|
2632
2674
|
readPreference: AI_ASSISTANT_READ_PREFERENCE
|
|
2633
2675
|
})];
|
|
2634
|
-
case
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
case
|
|
2638
|
-
case
|
|
2639
|
-
|
|
2640
|
-
return [3 /*break*/,
|
|
2641
|
-
case
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
if (
|
|
2676
|
+
case 38:
|
|
2677
|
+
_h.nameMatchCount = _r.sent();
|
|
2678
|
+
_r.label = 39;
|
|
2679
|
+
case 39: return [3 /*break*/, 41];
|
|
2680
|
+
case 40:
|
|
2681
|
+
_j = _r.sent();
|
|
2682
|
+
return [3 /*break*/, 41];
|
|
2683
|
+
case 41:
|
|
2684
|
+
_r.trys.push([41, 44, , 45]);
|
|
2685
|
+
_k = probeDocs;
|
|
2686
|
+
if (_k) return [3 /*break*/, 43];
|
|
2645
2687
|
return [4 /*yield*/, fetchAssistantProbeDocs({
|
|
2646
2688
|
db: db,
|
|
2647
2689
|
collection: collection,
|
|
@@ -2650,56 +2692,56 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2650
2692
|
isSuperAdmin: isSuperAdmin,
|
|
2651
2693
|
includeClientScope: shouldScopeByClient
|
|
2652
2694
|
})];
|
|
2653
|
-
case
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
case
|
|
2657
|
-
probeDocs =
|
|
2695
|
+
case 42:
|
|
2696
|
+
_k = (_r.sent());
|
|
2697
|
+
_r.label = 43;
|
|
2698
|
+
case 43:
|
|
2699
|
+
probeDocs = _k;
|
|
2658
2700
|
if (probeDocs.length && nameFields.length) {
|
|
2659
2701
|
diagnostics.chemicalIdDetected = detectChemicalIdFromProbe(probeDocs, nameFields);
|
|
2660
2702
|
}
|
|
2661
|
-
return [3 /*break*/,
|
|
2662
|
-
case
|
|
2663
|
-
|
|
2664
|
-
return [3 /*break*/,
|
|
2665
|
-
case
|
|
2666
|
-
|
|
2703
|
+
return [3 /*break*/, 45];
|
|
2704
|
+
case 44:
|
|
2705
|
+
_l = _r.sent();
|
|
2706
|
+
return [3 /*break*/, 45];
|
|
2707
|
+
case 45:
|
|
2708
|
+
_r.trys.push([45, 49, , 50]);
|
|
2667
2709
|
return [4 /*yield*/, listAssistantCollections(db, dbName)];
|
|
2668
|
-
case
|
|
2669
|
-
allCollections =
|
|
2710
|
+
case 46:
|
|
2711
|
+
allCollections = _r.sent();
|
|
2670
2712
|
base = stripVersionSuffix(collection.startsWith('report-') ? collection.slice('report-'.length) : collection);
|
|
2671
2713
|
alt = collection.startsWith('report-') ? base : "report-".concat(base);
|
|
2672
|
-
if (!(alt && alt !== collection && allCollections.includes(alt))) return [3 /*break*/,
|
|
2714
|
+
if (!(alt && alt !== collection && allCollections.includes(alt))) return [3 /*break*/, 48];
|
|
2673
2715
|
return [4 /*yield*/, db.collection(alt).countDocuments({}, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
|
|
2674
|
-
case
|
|
2675
|
-
altCount =
|
|
2716
|
+
case 47:
|
|
2717
|
+
altCount = _r.sent();
|
|
2676
2718
|
diagnostics.alternateCollection = alt;
|
|
2677
2719
|
diagnostics.alternateCollectionCount = altCount;
|
|
2678
|
-
|
|
2679
|
-
case
|
|
2680
|
-
case
|
|
2681
|
-
|
|
2682
|
-
return [3 /*break*/,
|
|
2683
|
-
case
|
|
2720
|
+
_r.label = 48;
|
|
2721
|
+
case 48: return [3 /*break*/, 50];
|
|
2722
|
+
case 49:
|
|
2723
|
+
_m = _r.sent();
|
|
2724
|
+
return [3 /*break*/, 50];
|
|
2725
|
+
case 50:
|
|
2684
2726
|
fallbackMeta.zeroDiagnostics = diagnostics;
|
|
2685
|
-
|
|
2686
|
-
case
|
|
2727
|
+
_r.label = 51;
|
|
2728
|
+
case 51:
|
|
2687
2729
|
total = null;
|
|
2688
|
-
if (!normalized.includeTotal) return [3 /*break*/,
|
|
2730
|
+
if (!normalized.includeTotal) return [3 /*break*/, 53];
|
|
2689
2731
|
return [4 /*yield*/, db.collection(collection).countDocuments(executedQuery, { readPreference: AI_ASSISTANT_READ_PREFERENCE })];
|
|
2690
|
-
case
|
|
2691
|
-
total =
|
|
2692
|
-
|
|
2693
|
-
case
|
|
2732
|
+
case 52:
|
|
2733
|
+
total = _r.sent();
|
|
2734
|
+
_r.label = 53;
|
|
2735
|
+
case 53:
|
|
2694
2736
|
sanitizedDocuments = isSuperAdmin
|
|
2695
2737
|
? documents
|
|
2696
2738
|
: documents.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
|
|
2697
2739
|
requestedFields = resolveProjectionRequestedFields(findOptions.projection);
|
|
2698
|
-
if (!(sanitizedDocuments.length && requestedFields.length)) return [3 /*break*/,
|
|
2740
|
+
if (!(sanitizedDocuments.length && requestedFields.length)) return [3 /*break*/, 57];
|
|
2699
2741
|
missingFields = requestedFields.filter(function (field) { return !hasNonEmptyValue(sanitizedDocuments, field, { treatObjectLikeAsEmpty: true }); });
|
|
2700
|
-
if (!missingFields.length) return [3 /*break*/,
|
|
2701
|
-
|
|
2702
|
-
if (
|
|
2742
|
+
if (!missingFields.length) return [3 /*break*/, 57];
|
|
2743
|
+
_o = probeDocs;
|
|
2744
|
+
if (_o) return [3 /*break*/, 55];
|
|
2703
2745
|
return [4 /*yield*/, fetchAssistantProbeDocs({
|
|
2704
2746
|
db: db,
|
|
2705
2747
|
collection: collection,
|
|
@@ -2708,26 +2750,26 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2708
2750
|
isSuperAdmin: isSuperAdmin,
|
|
2709
2751
|
includeClientScope: shouldScopeByClient
|
|
2710
2752
|
})];
|
|
2711
|
-
case
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
case
|
|
2715
|
-
probeDocs =
|
|
2716
|
-
if (!probeDocs.length) return [3 /*break*/,
|
|
2753
|
+
case 54:
|
|
2754
|
+
_o = (_r.sent());
|
|
2755
|
+
_r.label = 55;
|
|
2756
|
+
case 55:
|
|
2757
|
+
probeDocs = _o;
|
|
2758
|
+
if (!probeDocs.length) return [3 /*break*/, 57];
|
|
2717
2759
|
projectionAliases = resolveFieldAliases(probeDocs, missingFields, schemaFields);
|
|
2718
|
-
if (!Object.keys(projectionAliases).length) return [3 /*break*/,
|
|
2760
|
+
if (!Object.keys(projectionAliases).length) return [3 /*break*/, 57];
|
|
2719
2761
|
fallbackMeta.projectionAliases = {
|
|
2720
2762
|
aliases: projectionAliases,
|
|
2721
2763
|
attempted: true,
|
|
2722
2764
|
used: false
|
|
2723
2765
|
};
|
|
2724
2766
|
expandedProjection = expandProjectionWithAliases(findOptions.projection, projectionAliases);
|
|
2725
|
-
if (!(expandedProjection && expandedProjection !== findOptions.projection)) return [3 /*break*/,
|
|
2767
|
+
if (!(expandedProjection && expandedProjection !== findOptions.projection)) return [3 /*break*/, 57];
|
|
2726
2768
|
findOptions = __assign(__assign({}, findOptions), { projection: expandedProjection });
|
|
2727
2769
|
normalized.findOptions.projection = expandedProjection;
|
|
2728
2770
|
return [4 /*yield*/, db.collection(collection).find(executedQuery, findOptions).toArray()];
|
|
2729
|
-
case
|
|
2730
|
-
refreshedDocs =
|
|
2771
|
+
case 56:
|
|
2772
|
+
refreshedDocs = _r.sent();
|
|
2731
2773
|
if (refreshedDocs.length) {
|
|
2732
2774
|
documents = refreshedDocs;
|
|
2733
2775
|
sanitizedDocuments = isSuperAdmin
|
|
@@ -2735,9 +2777,9 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2735
2777
|
: refreshedDocs.map(function (doc) { return redactSensitiveFields((0, common_1.deepCopy)(doc)); });
|
|
2736
2778
|
fallbackMeta.projectionAliases.used = true;
|
|
2737
2779
|
}
|
|
2738
|
-
|
|
2739
|
-
case
|
|
2740
|
-
includeIds = ((
|
|
2780
|
+
_r.label = 57;
|
|
2781
|
+
case 57:
|
|
2782
|
+
includeIds = ((_q = input.options) === null || _q === void 0 ? void 0 : _q.includeIds) === true;
|
|
2741
2783
|
fieldAliases = resolveFieldAliases(sanitizedDocuments, requestedFields, schemaFields);
|
|
2742
2784
|
displayDocs = Object.keys(fieldAliases).length
|
|
2743
2785
|
? applyFieldAliasesForDisplay(sanitizedDocuments, fieldAliases)
|
|
@@ -2751,8 +2793,8 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2751
2793
|
idCustomer: customerId,
|
|
2752
2794
|
isSuperAdmin: isSuperAdmin
|
|
2753
2795
|
})];
|
|
2754
|
-
case
|
|
2755
|
-
idLookupDisplay =
|
|
2796
|
+
case 58:
|
|
2797
|
+
idLookupDisplay = _r.sent();
|
|
2756
2798
|
if (idLookupDisplay === null || idLookupDisplay === void 0 ? void 0 : idLookupDisplay.docs) {
|
|
2757
2799
|
displayDocs = idLookupDisplay.docs;
|
|
2758
2800
|
}
|
|
@@ -2761,10 +2803,11 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2761
2803
|
}
|
|
2762
2804
|
priorityFields = requestedFields.length
|
|
2763
2805
|
? __spreadArray(__spreadArray([], __read(requestedFields), false), __read(AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS), false) : AI_ASSISTANT_DISPLAY_PRIORITY_FIELDS;
|
|
2806
|
+
displayMaxRows = resolveAssistantReadDisplayMaxRows(normalized.findOptions.limit, sanitizedDocuments.length);
|
|
2764
2807
|
display = buildDisplayTable(displayDocs, {
|
|
2765
2808
|
includeIds: includeIds,
|
|
2766
2809
|
maxColumns: AI_ASSISTANT_DISPLAY_MAX_COLUMNS,
|
|
2767
|
-
maxRows:
|
|
2810
|
+
maxRows: displayMaxRows,
|
|
2768
2811
|
priorityFields: priorityFields,
|
|
2769
2812
|
includeGroupFromId: false
|
|
2770
2813
|
});
|
|
@@ -4212,30 +4255,81 @@ function resolveAssistantRevenueByTimeRequest(text, scope) {
|
|
|
4212
4255
|
amount: Math.min(Math.max((0, common_1.round)(amount), 1), 400)
|
|
4213
4256
|
};
|
|
4214
4257
|
}
|
|
4258
|
+
function buildAssistantTrimmedStringExpr(value) {
|
|
4259
|
+
return {
|
|
4260
|
+
$trim: {
|
|
4261
|
+
input: {
|
|
4262
|
+
$convert: {
|
|
4263
|
+
input: value,
|
|
4264
|
+
to: 'string',
|
|
4265
|
+
onError: '',
|
|
4266
|
+
onNull: ''
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4269
|
+
}
|
|
4270
|
+
};
|
|
4271
|
+
}
|
|
4272
|
+
function buildAssistantInvoiceCustomerLabelExpr() {
|
|
4273
|
+
return {
|
|
4274
|
+
$let: {
|
|
4275
|
+
vars: {
|
|
4276
|
+
customer_name: buildAssistantTrimmedStringExpr('$customer_name'),
|
|
4277
|
+
customer_fullname: buildAssistantTrimmedStringExpr('$customer.fullname'),
|
|
4278
|
+
customer_nested_name: buildAssistantTrimmedStringExpr('$customer.name'),
|
|
4279
|
+
customer_scalar: buildAssistantTrimmedStringExpr('$customer'),
|
|
4280
|
+
client_name: buildAssistantTrimmedStringExpr('$client_name'),
|
|
4281
|
+
client_fullname: buildAssistantTrimmedStringExpr('$client.fullname'),
|
|
4282
|
+
client_nested_name: buildAssistantTrimmedStringExpr('$client.name'),
|
|
4283
|
+
client_scalar: buildAssistantTrimmedStringExpr('$client'),
|
|
4284
|
+
id_customer: buildAssistantTrimmedStringExpr('$id_customer'),
|
|
4285
|
+
id_client: buildAssistantTrimmedStringExpr('$id_client')
|
|
4286
|
+
},
|
|
4287
|
+
in: {
|
|
4288
|
+
$switch: {
|
|
4289
|
+
branches: [
|
|
4290
|
+
{ case: { $gt: [{ $strLenCP: '$$customer_name' }, 0] }, then: '$$customer_name' },
|
|
4291
|
+
{ case: { $gt: [{ $strLenCP: '$$customer_fullname' }, 0] }, then: '$$customer_fullname' },
|
|
4292
|
+
{ case: { $gt: [{ $strLenCP: '$$customer_nested_name' }, 0] }, then: '$$customer_nested_name' },
|
|
4293
|
+
{ case: { $gt: [{ $strLenCP: '$$customer_scalar' }, 0] }, then: '$$customer_scalar' },
|
|
4294
|
+
{ case: { $gt: [{ $strLenCP: '$$client_name' }, 0] }, then: '$$client_name' },
|
|
4295
|
+
{ case: { $gt: [{ $strLenCP: '$$client_fullname' }, 0] }, then: '$$client_fullname' },
|
|
4296
|
+
{ case: { $gt: [{ $strLenCP: '$$client_nested_name' }, 0] }, then: '$$client_nested_name' },
|
|
4297
|
+
{ case: { $gt: [{ $strLenCP: '$$client_scalar' }, 0] }, then: '$$client_scalar' },
|
|
4298
|
+
{ case: { $gt: [{ $strLenCP: '$$id_customer' }, 0] }, then: '$$id_customer' },
|
|
4299
|
+
{ case: { $gt: [{ $strLenCP: '$$id_client' }, 0] }, then: '$$id_client' }
|
|
4300
|
+
],
|
|
4301
|
+
default: 'Unknown Customer'
|
|
4302
|
+
}
|
|
4303
|
+
}
|
|
4304
|
+
}
|
|
4305
|
+
};
|
|
4306
|
+
}
|
|
4307
|
+
function resolveAssistantRevenueByTimePipelineLimit(request, scope) {
|
|
4308
|
+
var amount = Math.min(Math.max((0, common_1.round)(request.amount), 1), 400);
|
|
4309
|
+
if (scope !== 'by_customer') {
|
|
4310
|
+
return Math.min(Math.max(amount * 2, 20), 200);
|
|
4311
|
+
}
|
|
4312
|
+
// Customer breakdowns need much higher pre-pivot row coverage so each customer appears.
|
|
4313
|
+
var perBucketTargets = {
|
|
4314
|
+
day: 120,
|
|
4315
|
+
week: 220,
|
|
4316
|
+
month: 350,
|
|
4317
|
+
quarter: 450,
|
|
4318
|
+
year: 600
|
|
4319
|
+
};
|
|
4320
|
+
var perBucketTarget = perBucketTargets[request.grain] || 300;
|
|
4321
|
+
return Math.min(Math.max(amount * perBucketTarget, 400), 5000);
|
|
4322
|
+
}
|
|
4215
4323
|
function buildAssistantInvoiceRevenueByTimePipeline(request, scope) {
|
|
4216
4324
|
var _a, _b, _c;
|
|
4217
4325
|
if (scope === void 0) { scope = 'overall'; }
|
|
4218
4326
|
var grain = request.grain;
|
|
4219
4327
|
var amount = Math.min(Math.max((0, common_1.round)(request.amount), 1), 400);
|
|
4220
4328
|
var byCustomer = scope === 'by_customer';
|
|
4329
|
+
var limit = resolveAssistantRevenueByTimePipelineLimit(request, scope);
|
|
4221
4330
|
var effectiveDateExpr = { $ifNull: ['$date_paid', { $ifNull: ['$date_invoiced', '$createdAt'] }] };
|
|
4222
4331
|
var effectiveTotalExpr = { $ifNull: ['$paid_total', '$grand_total'] };
|
|
4223
|
-
var customerExpr =
|
|
4224
|
-
$ifNull: [
|
|
4225
|
-
'$customer_name',
|
|
4226
|
-
{
|
|
4227
|
-
$ifNull: [
|
|
4228
|
-
'$customer.fullname',
|
|
4229
|
-
{
|
|
4230
|
-
$ifNull: [
|
|
4231
|
-
'$customer.name',
|
|
4232
|
-
{ $ifNull: [{ $toString: '$id_customer' }, 'Unknown Customer'] }
|
|
4233
|
-
]
|
|
4234
|
-
}
|
|
4235
|
-
]
|
|
4236
|
-
}
|
|
4237
|
-
]
|
|
4238
|
-
};
|
|
4332
|
+
var customerExpr = buildAssistantInvoiceCustomerLabelExpr();
|
|
4239
4333
|
var startDateExpr = grain === 'quarter'
|
|
4240
4334
|
? { $dateSubtract: { startDate: '$$NOW', unit: 'month', amount: amount * 3 } }
|
|
4241
4335
|
: { $dateSubtract: { startDate: '$$NOW', unit: grain, amount: amount } };
|
|
@@ -4267,7 +4361,7 @@ function buildAssistantInvoiceRevenueByTimePipeline(request, scope) {
|
|
|
4267
4361
|
$project: __assign(__assign({ _id: 0 }, (byCustomer ? { customer: '$_id.customer' } : {})), { quarter: { $concat: [{ $toString: '$_id.year' }, '-Q', { $toString: '$_id.quarter' }] }, total_revenue: 1 })
|
|
4268
4362
|
},
|
|
4269
4363
|
{ $sort: byCustomer ? { customer: 1, quarter: 1 } : { quarter: 1 } },
|
|
4270
|
-
{ $limit:
|
|
4364
|
+
{ $limit: limit }
|
|
4271
4365
|
], false);
|
|
4272
4366
|
}
|
|
4273
4367
|
if (grain === 'year') {
|
|
@@ -4284,7 +4378,7 @@ function buildAssistantInvoiceRevenueByTimePipeline(request, scope) {
|
|
|
4284
4378
|
$project: __assign(__assign({ _id: 0 }, (byCustomer ? { customer: '$_id.customer' } : {})), { year: '$_id.year', total_revenue: 1 })
|
|
4285
4379
|
},
|
|
4286
4380
|
{ $sort: byCustomer ? { customer: 1, year: 1 } : { year: 1 } },
|
|
4287
|
-
{ $limit:
|
|
4381
|
+
{ $limit: limit }
|
|
4288
4382
|
], false);
|
|
4289
4383
|
}
|
|
4290
4384
|
var bucketField = grain;
|
|
@@ -4314,7 +4408,7 @@ function buildAssistantInvoiceRevenueByTimePipeline(request, scope) {
|
|
|
4314
4408
|
}, _a.total_revenue = 1, _a))
|
|
4315
4409
|
},
|
|
4316
4410
|
{ $sort: byCustomer ? (_b = { customer: 1 }, _b[bucketField] = 1, _b) : (_c = {}, _c[bucketField] = 1, _c) },
|
|
4317
|
-
{ $limit:
|
|
4411
|
+
{ $limit: limit }
|
|
4318
4412
|
], false);
|
|
4319
4413
|
}
|
|
4320
4414
|
function isAssistantRevenueByTimeHeuristicDirective(directive) {
|
|
@@ -4325,8 +4419,18 @@ function isAssistantBlendRedUltraLiftHeuristicDirective(directive) {
|
|
|
4325
4419
|
var rawLine = normalizeOptionalString(directive === null || directive === void 0 ? void 0 : directive.rawLine).toLowerCase();
|
|
4326
4420
|
return rawLine.includes('heuristic_agg(blend-red-ultra-lift)');
|
|
4327
4421
|
}
|
|
4422
|
+
function isAssistantActiveClientsHeuristicDirective(directive) {
|
|
4423
|
+
var rawLine = normalizeOptionalString(directive === null || directive === void 0 ? void 0 : directive.rawLine).toLowerCase();
|
|
4424
|
+
return rawLine.includes('heuristic_read(active-clients-count)');
|
|
4425
|
+
}
|
|
4426
|
+
function isAssistantInvoiceTopCustomersHeuristicDirective(directive) {
|
|
4427
|
+
var rawLine = normalizeOptionalString(directive === null || directive === void 0 ? void 0 : directive.rawLine).toLowerCase();
|
|
4428
|
+
return rawLine.includes('heuristic_agg(invoice-top-customers)');
|
|
4429
|
+
}
|
|
4328
4430
|
function isAssistantDeterministicHeuristicDirective(directive) {
|
|
4329
4431
|
return isAssistantRevenueByTimeHeuristicDirective(directive)
|
|
4432
|
+
|| isAssistantActiveClientsHeuristicDirective(directive)
|
|
4433
|
+
|| isAssistantInvoiceTopCustomersHeuristicDirective(directive)
|
|
4330
4434
|
|| isAssistantBlendRedUltraLiftHeuristicDirective(directive);
|
|
4331
4435
|
}
|
|
4332
4436
|
function buildAssistantHeuristicDirective(message, collectionHints) {
|
|
@@ -4334,14 +4438,58 @@ function buildAssistantHeuristicDirective(message, collectionHints) {
|
|
|
4334
4438
|
if (!text) {
|
|
4335
4439
|
return null;
|
|
4336
4440
|
}
|
|
4441
|
+
if (/\bhow\s+many\b.*\bactive\b.*\b(clients?|customers?)\b/.test(text)
|
|
4442
|
+
|| /\bactive\b.*\b(clients?|customers?)\b.*\bhow\s+many\b/.test(text)) {
|
|
4443
|
+
var mergedHints = mergeAssistantHintValues(collectionHints, resolveAssistantDefaultCollectionHints(message));
|
|
4444
|
+
var customerCollection = mergedHints.includes('customers')
|
|
4445
|
+
? 'customers'
|
|
4446
|
+
: (mergedHints.includes('clients') ? 'clients' : 'customers');
|
|
4447
|
+
return {
|
|
4448
|
+
type: 'read',
|
|
4449
|
+
payload: {
|
|
4450
|
+
collection: customerCollection,
|
|
4451
|
+
permissionView: '/client/list',
|
|
4452
|
+
query: {
|
|
4453
|
+
$or: [
|
|
4454
|
+
{ status: { $regex: '^active$', $options: 'i' } },
|
|
4455
|
+
{ state: { $regex: '^active$', $options: 'i' } },
|
|
4456
|
+
{ active: true },
|
|
4457
|
+
{ is_active: true },
|
|
4458
|
+
{ enabled: true },
|
|
4459
|
+
{ is_enabled: true }
|
|
4460
|
+
]
|
|
4461
|
+
},
|
|
4462
|
+
options: {
|
|
4463
|
+
projection: {
|
|
4464
|
+
status: 1,
|
|
4465
|
+
state: 1,
|
|
4466
|
+
active: 1,
|
|
4467
|
+
is_active: 1,
|
|
4468
|
+
enabled: 1,
|
|
4469
|
+
is_enabled: 1
|
|
4470
|
+
},
|
|
4471
|
+
limit: 0,
|
|
4472
|
+
includeTotal: true
|
|
4473
|
+
}
|
|
4474
|
+
},
|
|
4475
|
+
cleaned: '',
|
|
4476
|
+
rawLine: 'HEURISTIC_READ(active-clients-count)'
|
|
4477
|
+
};
|
|
4478
|
+
}
|
|
4337
4479
|
var revenueByCustomerTime = resolveAssistantRevenueByTimeRequest(text, 'by_customer');
|
|
4338
4480
|
if (revenueByCustomerTime) {
|
|
4481
|
+
var customerLimit = resolveAssistantRevenueByTimePipelineLimit(revenueByCustomerTime, 'by_customer');
|
|
4339
4482
|
return {
|
|
4340
4483
|
type: 'aggregate',
|
|
4341
4484
|
payload: {
|
|
4342
4485
|
collection: 'invoices',
|
|
4343
4486
|
permissionView: '/invoice/list',
|
|
4344
|
-
pipeline: buildAssistantInvoiceRevenueByTimePipeline(revenueByCustomerTime, 'by_customer')
|
|
4487
|
+
pipeline: buildAssistantInvoiceRevenueByTimePipeline(revenueByCustomerTime, 'by_customer'),
|
|
4488
|
+
options: {
|
|
4489
|
+
allowDiskUse: true,
|
|
4490
|
+
export: true,
|
|
4491
|
+
limit: customerLimit
|
|
4492
|
+
}
|
|
4345
4493
|
},
|
|
4346
4494
|
cleaned: '',
|
|
4347
4495
|
rawLine: "HEURISTIC_AGG(invoice-revenue-time-customer-".concat(revenueByCustomerTime.grain, ")")
|
|
@@ -4513,7 +4661,7 @@ function buildAssistantHeuristicDirective(message, collectionHints) {
|
|
|
4513
4661
|
pipeline: [
|
|
4514
4662
|
{
|
|
4515
4663
|
$addFields: {
|
|
4516
|
-
effective_date: { $ifNull: ['$date_paid', '$date_invoiced', '$createdAt'] },
|
|
4664
|
+
effective_date: { $ifNull: ['$date_paid', { $ifNull: ['$date_invoiced', '$createdAt'] }] },
|
|
4517
4665
|
effective_total: { $ifNull: ['$paid_total', '$grand_total'] }
|
|
4518
4666
|
}
|
|
4519
4667
|
},
|
|
@@ -4527,7 +4675,7 @@ function buildAssistantHeuristicDirective(message, collectionHints) {
|
|
|
4527
4675
|
},
|
|
4528
4676
|
{
|
|
4529
4677
|
$group: {
|
|
4530
|
-
_id:
|
|
4678
|
+
_id: buildAssistantInvoiceCustomerLabelExpr(),
|
|
4531
4679
|
invoice_total: { $sum: { $ifNull: ['$effective_total', 0] } },
|
|
4532
4680
|
invoice_count: { $sum: 1 }
|
|
4533
4681
|
}
|
|
@@ -5284,18 +5432,20 @@ function buildAssistantToolResultPayload(directive, toolResponse, requestMessage
|
|
|
5284
5432
|
};
|
|
5285
5433
|
}
|
|
5286
5434
|
function resolveAssistantToolResultResponseMaxRows(directive, directivePayload, rowCount) {
|
|
5287
|
-
var _a;
|
|
5435
|
+
var _a, _b;
|
|
5288
5436
|
if (directive.type !== 'aggregate') {
|
|
5289
5437
|
return AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS;
|
|
5290
5438
|
}
|
|
5291
|
-
var
|
|
5292
|
-
|
|
5439
|
+
var exportMode = ((_a = directivePayload === null || directivePayload === void 0 ? void 0 : directivePayload.options) === null || _a === void 0 ? void 0 : _a.export) === true;
|
|
5440
|
+
var maxRows = exportMode ? AI_ASSISTANT_MONGO_EXPORT_MAX_LIMIT : AI_ASSISTANT_MONGO_MAX_LIMIT;
|
|
5441
|
+
var requestedLimit = typeof ((_b = directivePayload === null || directivePayload === void 0 ? void 0 : directivePayload.options) === null || _b === void 0 ? void 0 : _b.limit) === 'number'
|
|
5442
|
+
? Math.min(Math.max((0, common_1.round)(directivePayload.options.limit), 0), maxRows)
|
|
5293
5443
|
: 0;
|
|
5294
5444
|
if (requestedLimit > 0) {
|
|
5295
5445
|
return requestedLimit;
|
|
5296
5446
|
}
|
|
5297
5447
|
if (typeof rowCount === 'number' && rowCount > 0) {
|
|
5298
|
-
return Math.min(rowCount,
|
|
5448
|
+
return Math.min(rowCount, maxRows);
|
|
5299
5449
|
}
|
|
5300
5450
|
return AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS;
|
|
5301
5451
|
}
|
|
@@ -7614,20 +7764,26 @@ function isAssistantMarkdownTableRowLine(line) {
|
|
|
7614
7764
|
return /^\|.*\|$/.test(trimmed);
|
|
7615
7765
|
}
|
|
7616
7766
|
function ensureAssistantMinimumDisplayColumns(display) {
|
|
7767
|
+
var _a;
|
|
7617
7768
|
if (!display || !Array.isArray(display.columns) || display.columns.length !== 1) {
|
|
7618
7769
|
return display;
|
|
7619
7770
|
}
|
|
7620
7771
|
var primary = display.columns[0] || 'Result';
|
|
7621
|
-
var rows = Array.isArray(display.rows)
|
|
7622
|
-
|
|
7623
|
-
|
|
7624
|
-
|
|
7625
|
-
|
|
7626
|
-
|
|
7627
|
-
|
|
7628
|
-
|
|
7629
|
-
|
|
7630
|
-
|
|
7772
|
+
var rows = Array.isArray(display.rows) ? display.rows : [];
|
|
7773
|
+
if (!rows.length) {
|
|
7774
|
+
return display;
|
|
7775
|
+
}
|
|
7776
|
+
var labels = rows
|
|
7777
|
+
.map(function (row) { return normalizeOptionalString((row || {})[primary]) || 'Unknown'; })
|
|
7778
|
+
.filter(Boolean);
|
|
7779
|
+
var uniqueLabels = Array.from(new Set(labels));
|
|
7780
|
+
if (uniqueLabels.length !== 1) {
|
|
7781
|
+
return display;
|
|
7782
|
+
}
|
|
7783
|
+
var totalCount = typeof display.rowCount === 'number' && display.rowCount > 0
|
|
7784
|
+
? display.rowCount
|
|
7785
|
+
: rows.length;
|
|
7786
|
+
return __assign(__assign({}, display), { columns: [primary, 'Count'], rows: [(_a = {}, _a[primary] = uniqueLabels[0], _a.Count = totalCount, _a)], rowCount: 1, truncated: false });
|
|
7631
7787
|
}
|
|
7632
7788
|
function applyAssistantDisplayTableToResponse(value, display) {
|
|
7633
7789
|
if (!display || !Array.isArray(display.rows)) {
|
|
@@ -7636,14 +7792,24 @@ function applyAssistantDisplayTableToResponse(value, display) {
|
|
|
7636
7792
|
var normalizedDisplay = ensureAssistantMinimumDisplayColumns(display);
|
|
7637
7793
|
if (!display.rows.length) {
|
|
7638
7794
|
var cleaned_1 = stripAssistantMarkdownTables(value);
|
|
7639
|
-
var
|
|
7640
|
-
?
|
|
7641
|
-
|
|
7642
|
-
|
|
7643
|
-
|
|
7644
|
-
|
|
7645
|
-
|
|
7646
|
-
|
|
7795
|
+
var rowCount = typeof normalizedDisplay.rowCount === 'number' && normalizedDisplay.rowCount > 0
|
|
7796
|
+
? normalizedDisplay.rowCount
|
|
7797
|
+
: 0;
|
|
7798
|
+
var tableDisplay = rowCount > 0
|
|
7799
|
+
? {
|
|
7800
|
+
columns: ['Metric', 'Value'],
|
|
7801
|
+
rows: [{ Metric: 'Rows matched', Value: rowCount }],
|
|
7802
|
+
rowCount: 1,
|
|
7803
|
+
truncated: false,
|
|
7804
|
+
includeIds: false
|
|
7805
|
+
}
|
|
7806
|
+
: {
|
|
7807
|
+
columns: ['Result', 'Details'],
|
|
7808
|
+
rows: [{ Result: 'No matching rows', Details: '' }],
|
|
7809
|
+
rowCount: 0,
|
|
7810
|
+
truncated: false,
|
|
7811
|
+
includeIds: false
|
|
7812
|
+
};
|
|
7647
7813
|
var emptyTable = formatDisplayTableMarkdown(tableDisplay);
|
|
7648
7814
|
if (!emptyTable) {
|
|
7649
7815
|
return cleaned_1 || value;
|
|
@@ -7750,6 +7916,15 @@ function resolveAssistantDatabaseName(database, mongoConfig) {
|
|
|
7750
7916
|
}
|
|
7751
7917
|
return dbName;
|
|
7752
7918
|
}
|
|
7919
|
+
function resolveAssistantReadDisplayMaxRows(limit, rowCount) {
|
|
7920
|
+
if (typeof limit === 'number' && Number.isFinite(limit) && limit > 0) {
|
|
7921
|
+
return Math.max((0, common_1.round)(limit), 1);
|
|
7922
|
+
}
|
|
7923
|
+
if (typeof rowCount === 'number' && Number.isFinite(rowCount) && rowCount > 0) {
|
|
7924
|
+
return Math.min(Math.max((0, common_1.round)(rowCount), 1), AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS);
|
|
7925
|
+
}
|
|
7926
|
+
return AI_ASSISTANT_DISPLAY_PREVIEW_MAX_ROWS;
|
|
7927
|
+
}
|
|
7753
7928
|
function normalizeAssistantFindOptions(options) {
|
|
7754
7929
|
var normalized = options || {};
|
|
7755
7930
|
var exportMode = normalized.export === true;
|
|
@@ -9924,6 +10099,67 @@ function isDateCondition(value) {
|
|
|
9924
10099
|
}
|
|
9925
10100
|
return false;
|
|
9926
10101
|
}
|
|
10102
|
+
function isAssistantActiveFieldPath(field) {
|
|
10103
|
+
var normalized = normalizeOptionalString(field).toLowerCase();
|
|
10104
|
+
if (!normalized) {
|
|
10105
|
+
return false;
|
|
10106
|
+
}
|
|
10107
|
+
var leaf = normalized.split('.').pop() || normalized;
|
|
10108
|
+
return ['status', 'state', 'active', 'is_active', 'isactive', 'enabled', 'is_enabled', 'isenabled'].includes(leaf);
|
|
10109
|
+
}
|
|
10110
|
+
function isAssistantActiveCondition(value) {
|
|
10111
|
+
if (typeof value === 'boolean') {
|
|
10112
|
+
return value === true;
|
|
10113
|
+
}
|
|
10114
|
+
if (typeof value === 'string') {
|
|
10115
|
+
return /^active$/i.test(value.trim());
|
|
10116
|
+
}
|
|
10117
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
10118
|
+
return false;
|
|
10119
|
+
}
|
|
10120
|
+
var regexValue = value.$regex;
|
|
10121
|
+
if (regexValue instanceof RegExp) {
|
|
10122
|
+
return /active/i.test(regexValue.source);
|
|
10123
|
+
}
|
|
10124
|
+
if (typeof regexValue === 'string' && /active/i.test(regexValue)) {
|
|
10125
|
+
return true;
|
|
10126
|
+
}
|
|
10127
|
+
var eqValue = value.$eq;
|
|
10128
|
+
if (typeof eqValue === 'boolean' && eqValue === true) {
|
|
10129
|
+
return true;
|
|
10130
|
+
}
|
|
10131
|
+
if (typeof eqValue === 'string' && /^active$/i.test(eqValue.trim())) {
|
|
10132
|
+
return true;
|
|
10133
|
+
}
|
|
10134
|
+
var inValues = Array.isArray(value.$in) ? value.$in : [];
|
|
10135
|
+
if (inValues.some(function (entry) { return (typeof entry === 'boolean' && entry === true)
|
|
10136
|
+
|| (typeof entry === 'string' && /^active$/i.test(entry.trim())); })) {
|
|
10137
|
+
return true;
|
|
10138
|
+
}
|
|
10139
|
+
return false;
|
|
10140
|
+
}
|
|
10141
|
+
function collectAssistantActiveMatchFields(query) {
|
|
10142
|
+
var fields = collectMatchFieldsByCondition(query, function (field, condition) { return isAssistantActiveFieldPath(field) && isAssistantActiveCondition(condition); });
|
|
10143
|
+
return Array.from(new Set(fields));
|
|
10144
|
+
}
|
|
10145
|
+
function resolveReadActiveStatusFallback(query, probeDocs) {
|
|
10146
|
+
var fields = collectAssistantActiveMatchFields(query);
|
|
10147
|
+
if (!fields.length || !Array.isArray(probeDocs) || !probeDocs.length) {
|
|
10148
|
+
return null;
|
|
10149
|
+
}
|
|
10150
|
+
var hasAnyFieldData = fields.some(function (field) { return hasNonEmptyValue(probeDocs, field, { treatObjectLikeAsEmpty: true }); });
|
|
10151
|
+
if (hasAnyFieldData) {
|
|
10152
|
+
return null;
|
|
10153
|
+
}
|
|
10154
|
+
var stripped = stripQueryFieldPathsDeepWithMeta(query, fields);
|
|
10155
|
+
if (!stripped.changed || !stripped.value || typeof stripped.value !== 'object') {
|
|
10156
|
+
return null;
|
|
10157
|
+
}
|
|
10158
|
+
return {
|
|
10159
|
+
query: stripped.value,
|
|
10160
|
+
fields: fields
|
|
10161
|
+
};
|
|
10162
|
+
}
|
|
9927
10163
|
function isChemicalFieldPath(field) {
|
|
9928
10164
|
var normalized = normalizeOptionalString(field).toLowerCase();
|
|
9929
10165
|
return normalized.includes('chemical');
|
|
@@ -11172,6 +11408,10 @@ function resolveAssistantDefaultCollectionHints(message) {
|
|
|
11172
11408
|
if (/\bcustomers?\b/.test(text)) {
|
|
11173
11409
|
push('customers');
|
|
11174
11410
|
}
|
|
11411
|
+
if (/\bclients?\b/.test(text)) {
|
|
11412
|
+
push('customers');
|
|
11413
|
+
push('clients');
|
|
11414
|
+
}
|
|
11175
11415
|
return hints;
|
|
11176
11416
|
}
|
|
11177
11417
|
function buildCollectionRankingDebugFromTokens(tokens, collectionNames, max) {
|
|
@@ -11342,6 +11582,36 @@ function pickPreferredCollectionCandidate(ranked) {
|
|
|
11342
11582
|
}
|
|
11343
11583
|
return top;
|
|
11344
11584
|
}
|
|
11585
|
+
function normalizeAssistantCollectionOverrideName(value) {
|
|
11586
|
+
var normalized = normalizeOptionalString(value).toLowerCase();
|
|
11587
|
+
if (!normalized) {
|
|
11588
|
+
return '';
|
|
11589
|
+
}
|
|
11590
|
+
var withoutReportPrefix = normalized.startsWith('report-')
|
|
11591
|
+
? normalized.slice('report-'.length)
|
|
11592
|
+
: normalized;
|
|
11593
|
+
return stripVersionSuffix(withoutReportPrefix);
|
|
11594
|
+
}
|
|
11595
|
+
function isAssistantGenericCollectionName(value) {
|
|
11596
|
+
var normalized = normalizeAssistantCollectionOverrideName(value);
|
|
11597
|
+
if (!normalized) {
|
|
11598
|
+
return false;
|
|
11599
|
+
}
|
|
11600
|
+
return !normalized.includes('-') && !normalized.includes('_');
|
|
11601
|
+
}
|
|
11602
|
+
function isAssistantCollectionRefinementOf(currentCollection, genericCollection) {
|
|
11603
|
+
var current = normalizeAssistantCollectionOverrideName(currentCollection);
|
|
11604
|
+
var generic = normalizeAssistantCollectionOverrideName(genericCollection);
|
|
11605
|
+
if (!current || !generic || current === generic) {
|
|
11606
|
+
return false;
|
|
11607
|
+
}
|
|
11608
|
+
return current.startsWith("".concat(generic, "-"))
|
|
11609
|
+
|| current.endsWith("-".concat(generic))
|
|
11610
|
+
|| current.includes("-".concat(generic, "-"))
|
|
11611
|
+
|| current.startsWith("".concat(generic, "_"))
|
|
11612
|
+
|| current.endsWith("_".concat(generic))
|
|
11613
|
+
|| current.includes("_".concat(generic, "_"));
|
|
11614
|
+
}
|
|
11345
11615
|
function resolveAssistantCollectionOverride(collectionRanking, currentCollection) {
|
|
11346
11616
|
var _a, _b;
|
|
11347
11617
|
var ranked = Array.isArray(collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked) ? collectionRanking === null || collectionRanking === void 0 ? void 0 : collectionRanking.ranked : [];
|
|
@@ -11366,6 +11636,11 @@ function resolveAssistantCollectionOverride(collectionRanking, currentCollection
|
|
|
11366
11636
|
return null;
|
|
11367
11637
|
}
|
|
11368
11638
|
var currentScore = (_b = (_a = ranked.find(function (entry) { return entry.name === current; })) === null || _a === void 0 ? void 0 : _a.score) !== null && _b !== void 0 ? _b : 0;
|
|
11639
|
+
if (currentScore >= AI_ASSISTANT_COLLECTION_OVERRIDE_MIN_SCORE
|
|
11640
|
+
&& isAssistantGenericCollectionName(top.name)
|
|
11641
|
+
&& isAssistantCollectionRefinementOf(current, top.name)) {
|
|
11642
|
+
return null;
|
|
11643
|
+
}
|
|
11369
11644
|
var scoreGap = top.score - currentScore;
|
|
11370
11645
|
var currentIsVersion = isVersionCollectionName(current);
|
|
11371
11646
|
var topIsVersion = isVersionCollectionName(top.name);
|
|
@@ -11442,7 +11717,10 @@ var AI_ASSISTANT_BRIDGE_COLLECTION_ALIASES = {
|
|
|
11442
11717
|
reportchemicalblends: 'chemical-blends',
|
|
11443
11718
|
blend: 'chemical-blends',
|
|
11444
11719
|
blends: 'chemical-blends',
|
|
11445
|
-
invoice: 'invoices'
|
|
11720
|
+
invoice: 'invoices',
|
|
11721
|
+
client: 'customers',
|
|
11722
|
+
clients: 'customers',
|
|
11723
|
+
customer: 'customers'
|
|
11446
11724
|
};
|
|
11447
11725
|
var AI_ASSISTANT_DIRECT_COLLECTION_FALLBACK_ALLOWLIST = new Set([
|
|
11448
11726
|
'work-order-dynamics',
|
|
@@ -14374,6 +14652,44 @@ function normalizeAssistantRoutes(value) {
|
|
|
14374
14652
|
return "".concat(canonical).concat(suffix);
|
|
14375
14653
|
});
|
|
14376
14654
|
}
|
|
14655
|
+
function stripAssistantEmptyMarkdownTableRows(value) {
|
|
14656
|
+
var lines = String(value || '').split('\n');
|
|
14657
|
+
var output = [];
|
|
14658
|
+
var index = 0;
|
|
14659
|
+
while (index < lines.length) {
|
|
14660
|
+
var header = String(lines[index] || '').trim();
|
|
14661
|
+
var separator = String(lines[index + 1] || '').trim();
|
|
14662
|
+
var isTableHeader = /^\|.+\|$/.test(header);
|
|
14663
|
+
var isTableSeparator = /^\|?\s*:?-{3,}:?\s*(\|\s*:?-{3,}:?\s*)+\|?\s*$/.test(separator);
|
|
14664
|
+
if (!isTableHeader || !isTableSeparator) {
|
|
14665
|
+
output.push(lines[index]);
|
|
14666
|
+
index += 1;
|
|
14667
|
+
continue;
|
|
14668
|
+
}
|
|
14669
|
+
var tableStart = output.length;
|
|
14670
|
+
output.push(lines[index]);
|
|
14671
|
+
output.push(lines[index + 1]);
|
|
14672
|
+
index += 2;
|
|
14673
|
+
var keptRows = 0;
|
|
14674
|
+
while (index < lines.length) {
|
|
14675
|
+
var line = String(lines[index] || '');
|
|
14676
|
+
if (!line.trim() || !line.includes('|')) {
|
|
14677
|
+
break;
|
|
14678
|
+
}
|
|
14679
|
+
var cells = line.split('|').map(function (cell) { return cell.trim(); }).filter(Boolean);
|
|
14680
|
+
var hasContent = cells.some(function (cell) { return cell !== '-' && cell !== '---'; });
|
|
14681
|
+
if (hasContent) {
|
|
14682
|
+
output.push(line);
|
|
14683
|
+
keptRows += 1;
|
|
14684
|
+
}
|
|
14685
|
+
index += 1;
|
|
14686
|
+
}
|
|
14687
|
+
if (keptRows === 0) {
|
|
14688
|
+
output.splice(tableStart, 2);
|
|
14689
|
+
}
|
|
14690
|
+
}
|
|
14691
|
+
return output.join('\n').replace(/\n{3,}/g, '\n\n').trim();
|
|
14692
|
+
}
|
|
14377
14693
|
function sanitizeAssistantResponse(value) {
|
|
14378
14694
|
var raw = normalizeOptionalString(value);
|
|
14379
14695
|
if (!raw) {
|
|
@@ -14435,7 +14751,8 @@ function sanitizeAssistantResponse(value) {
|
|
|
14435
14751
|
if (!cleaned) {
|
|
14436
14752
|
return 'I can’t share code, but I can point you to files or explain behavior at a high level.';
|
|
14437
14753
|
}
|
|
14438
|
-
var
|
|
14754
|
+
var tableCleaned = stripAssistantEmptyMarkdownTableRows(cleaned);
|
|
14755
|
+
var normalizedCurrency = normalizeAssistantCurrencyText(tableCleaned || cleaned);
|
|
14439
14756
|
return normalizeAssistantRoutes(normalizedCurrency);
|
|
14440
14757
|
}
|
|
14441
14758
|
function evaluateAssistantGuardrails(message) {
|