@resolveio/server-lib 22.0.6 → 22.0.8
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.js +667 -168
- package/methods/ai-terminal.js.map +1 -1
- package/methods/report-builder.js +7 -2
- package/methods/report-builder.js.map +1 -1
- package/methods.ts +6 -0
- package/package.json +1 -1
package/methods/ai-terminal.js
CHANGED
|
@@ -162,6 +162,8 @@ var AI_ASSISTANT_ID_LOOKUP_CANDIDATE_LIMIT = 4;
|
|
|
162
162
|
var AI_ASSISTANT_NAME_MATCH_FALLBACK_MAX_FIELDS = 12;
|
|
163
163
|
var AI_ASSISTANT_CONTEXT_MAX_COLLECTIONS = 3;
|
|
164
164
|
var AI_ASSISTANT_CONTEXT_MAX_FIELDS_PER_COLLECTION = 24;
|
|
165
|
+
var AI_ASSISTANT_PLANNER_MAX_ROUTES = 200;
|
|
166
|
+
var AI_ASSISTANT_PLANNER_DEBUG_MAX_CHARS = 2000;
|
|
165
167
|
var AI_ASSISTANT_LOCALE = 'en-US';
|
|
166
168
|
var AI_ASSISTANT_CURRENCY_CODE = 'USD';
|
|
167
169
|
var AI_ASSISTANT_PROGRESS_TICKS = [
|
|
@@ -364,12 +366,65 @@ var AI_ASSISTANT_TERM_SYNONYMS = [
|
|
|
364
366
|
expansions: ['invoice', 'invoices', 'paid invoices', 'invoice payments', 'billing', 'sales']
|
|
365
367
|
}
|
|
366
368
|
];
|
|
369
|
+
var AI_ASSISTANT_REPORT_BUILDER_EXPERT_PLAYBOOK = [
|
|
370
|
+
'Report Builder Bridge Expert Playbook (execute in order for every data request):',
|
|
371
|
+
'1) Determine if data is required.',
|
|
372
|
+
'- If user asks for counts, lists, totals, trends, rankings, or "recent/last", run a report builder directive before answering.',
|
|
373
|
+
'',
|
|
374
|
+
'Report style mapping (always apply):',
|
|
375
|
+
'- Dated report: any breakdown over time (per day/week/month/quarter/year, trends, time-series comparisons).',
|
|
376
|
+
'- Grouped report: any nested headers, grouped buckets, grouped totals, or multi-level grouping dimensions.',
|
|
377
|
+
'- List report: simple flat records without grouped buckets or time-series grouping.',
|
|
378
|
+
'',
|
|
379
|
+
'2) Resolve the target dataset safely.',
|
|
380
|
+
'- Map user wording to internal collection names using routes, collection hints, field hints, and synonym expansion.',
|
|
381
|
+
'- Prefer report-* collections when permissionView is under /report.',
|
|
382
|
+
'- Never use *.versions unless user explicitly requests bug-history/version investigation.',
|
|
383
|
+
'- Never invent collection names or fields.',
|
|
384
|
+
'',
|
|
385
|
+
'3) Enforce permissions and scope in the directive.',
|
|
386
|
+
'- Always include permissionView.',
|
|
387
|
+
'- Assume non-super-admin unless explicitly told otherwise.',
|
|
388
|
+
'- Invoice-like collections require invoice view access.',
|
|
389
|
+
'- Customer portal users must stay in their own customer scope.',
|
|
390
|
+
'',
|
|
391
|
+
'4) Choose the right bridge tool.',
|
|
392
|
+
'- Use REPORT_BUILDER_READ for record lists, snapshots, detail lookups, and simple totals/counts.',
|
|
393
|
+
'- Use REPORT_BUILDER_AGG for grouped summaries, trends over time, rankings, and breakdowns.',
|
|
394
|
+
'',
|
|
395
|
+
'5) Build a minimal, high-signal query.',
|
|
396
|
+
'- Keep projection tight and limit rows (default 20 unless user asks for more).',
|
|
397
|
+
'- Add sort for deterministic output.',
|
|
398
|
+
'- Always sort by popular keys when available: name, company, item (then title/label/customer as fallbacks), ascending unless the user asks for a different order.',
|
|
399
|
+
'- If no popular key exists, use a stable fallback sort (createdAt/date_created then _id).',
|
|
400
|
+
'- Build filters with explicit boolean logic: use $and for required constraints and $or for alternate text/name matches.',
|
|
401
|
+
'- Use custom/calculated fields when the user asks for derived metrics (ratios, rates, margins, computed totals).',
|
|
402
|
+
'- Use collection joins/lookups when selected fields live across related collections.',
|
|
403
|
+
'- If multiple arrays are selected, link them by shared identifiers (_id or id_<x>) so rows are aligned and not duplicated by cartesian expansion.',
|
|
404
|
+
'- For relative dates, include an upper bound <= $$NOW unless user explicitly asks for future ranges.',
|
|
405
|
+
'- For invoice revenue, prefer paid_total fallback grand_total and paid/closed states when applicable.',
|
|
406
|
+
'',
|
|
407
|
+
'6) Reliability fallback sequence when result is empty.',
|
|
408
|
+
'- Re-check collection and date fields (date_created/createdAt/date_completed/date_paid variants).',
|
|
409
|
+
'- Run tiny probe (limit 1-3) to validate shape before concluding "no data".',
|
|
410
|
+
'- For name filters, verify date-only first; then apply tokenized regex and id/name lookup fallback.',
|
|
411
|
+
'',
|
|
412
|
+
'7) Output behavior after bridge response.',
|
|
413
|
+
'- Summarize the answer first in plain language.',
|
|
414
|
+
'- Then provide a markdown table with clean columns.',
|
|
415
|
+
'- Do not dump raw JSON.',
|
|
416
|
+
'- Do not claim certainty when data could not be fetched.',
|
|
417
|
+
'',
|
|
418
|
+
'8) Directive formatting requirement.',
|
|
419
|
+
'- End with exactly one REPORT_BUILDER_READ or REPORT_BUILDER_AGG line when data fetch is needed.',
|
|
420
|
+
'- Do not include extra directive lines or mixed directive types in one response.'
|
|
421
|
+
].join('\n');
|
|
367
422
|
var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
368
423
|
'You are the ResolveIO in-app AI assistant running with read-only access to the codebase.',
|
|
369
424
|
'Core rules:',
|
|
370
425
|
'- Never share code or file contents. All code is proprietary.',
|
|
371
426
|
'- Do not modify files, run destructive commands, or access databases directly.',
|
|
372
|
-
'- Read-only
|
|
427
|
+
'- Read-only data access is allowed only via the REPORT_BUILDER_READ/REPORT_BUILDER_AGG directives (see below).',
|
|
373
428
|
'- Do not access secrets, credentials, or user data.',
|
|
374
429
|
'- 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.',
|
|
375
430
|
'- Do not assist with hacking, bypassing security, or abuse.',
|
|
@@ -380,14 +435,14 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
380
435
|
'- If permissionView starts with /report/, prefer the report-* collection when both report and base collections exist.',
|
|
381
436
|
'- Map user wording to internal collections/fields yourself. Do not ask for property names unless required to run a query.',
|
|
382
437
|
'- Use term hints from context (synonym expansions) when mapping user language to collections.',
|
|
383
|
-
'- Do not guess or invent collections/fields. If unsure, verify in the codebase or run a small
|
|
384
|
-
'- Prefer running a small
|
|
385
|
-
'- For any data request (counts, lists, breakdowns, recent/last items), you MUST run a
|
|
438
|
+
'- Do not guess or invent collections/fields. If unsure, verify in the codebase or run a small REPORT_BUILDER_READ probe (limit 1-5) to learn the shape.',
|
|
439
|
+
'- Prefer running a small REPORT_BUILDER_READ probe over asking multiple questions.',
|
|
440
|
+
'- For any data request (counts, lists, breakdowns, recent/last items), you MUST run a REPORT_BUILDER_READ or REPORT_BUILDER_AGG before answering.',
|
|
386
441
|
'- Ask at most one clarifying question only when required to run a query or resolve missing details.',
|
|
387
442
|
'- If a field starts with id_ and refers to another collection, treat it as a foreign key and look up the related record when needed.',
|
|
388
443
|
'- When resolving id_* fields, prefer lookup definitions from collection schemas/report-builder lookup tables to choose the target collection and name fields.',
|
|
389
444
|
'- When the user provides a customer, well, or chemical name, use case-insensitive regex matching to find it. Assume the name exists and try to match it before asking questions.',
|
|
390
|
-
'- Use the codebase context to choose correct collections/fields/workflows and use
|
|
445
|
+
'- Use the codebase context to choose correct collections/fields/workflows and use REPORT_BUILDER_READ/REPORT_BUILDER_AGG to answer with real data when needed.',
|
|
391
446
|
'- Process (fast path): Queue -> Planning -> Grabbing Data -> Drafting response. Use regex/keyword matching to identify collections/models, draft a minimal query, run the tool, then format a table. This should be fast; avoid extra narration.',
|
|
392
447
|
'- Assume a relevant collection exists; if verification reads return zero data, report no data found instead of interrogating the user.',
|
|
393
448
|
'- Never claim "no data exists" unless you resolved a collection and executed a legitimate query (with fallback date fields when needed) that returned zero rows.',
|
|
@@ -427,11 +482,11 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
427
482
|
'- SUPPORT_TICKET_CREATE: <one-line summary>',
|
|
428
483
|
'- Only include that line when the user clearly wants a ticket created. Do not claim a ticket is created unless you include that line.',
|
|
429
484
|
'- 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.',
|
|
430
|
-
'
|
|
485
|
+
'Report builder bridge directives:',
|
|
431
486
|
'- If you need database data to answer, end your response with a single line exactly in this format:',
|
|
432
|
-
'-
|
|
487
|
+
'- REPORT_BUILDER_READ: {"collection":"<name>","query":{...},"options":{"projection":{...},"sort":{...},"limit":20},"permissionView":"</route>"}',
|
|
433
488
|
'- If you need grouped/aggregated data (totals by user, rankings, trends), end your response with a single line exactly in this format:',
|
|
434
|
-
'-
|
|
489
|
+
'- REPORT_BUILDER_AGG: {"collection":"<name>","pipeline":[...],"options":{"allowDiskUse":true,"limit":20},"permissionView":"</route>"}',
|
|
435
490
|
'- For invoice data, set permissionView to an invoice route (ex: /invoice/list or /report/invoice).',
|
|
436
491
|
'- For revenue/sales/billing questions, use invoices and sum paid_total (fallback to grand_total) with date_paid and Paid/Closed status when available.',
|
|
437
492
|
'- For relative date ranges (last/past/recent), include an upper bound <= $$NOW unless the user specifies a future end date.',
|
|
@@ -439,16 +494,165 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
|
|
|
439
494
|
'- Assume you are not a super admin unless explicitly told otherwise.',
|
|
440
495
|
'- Only request data when the user has permission for that module; invoice data requires invoice view access.',
|
|
441
496
|
'- If the user lacks permission, answer without data and explain how to view it in the app or request access.',
|
|
442
|
-
'- For simple counts or time-range totals, use
|
|
497
|
+
'- For simple counts or time-range totals, use REPORT_BUILDER_READ (includeTotal). For breakdowns, rankings, or sums grouped by a field, use REPORT_BUILDER_AGG.',
|
|
443
498
|
'- For performance, keep pipelines minimal: avoid $push arrays or large fields unless the user explicitly asks for them.',
|
|
444
499
|
'- For completion metrics (ex: "completed per day"), filter by completed status when applicable and use completion date fields; if completion dates are missing, fall back to createdAt/date_created and note the fallback.',
|
|
445
|
-
'- Before issuing
|
|
500
|
+
'- Before issuing REPORT_BUILDER_READ or REPORT_BUILDER_AGG, verify the collection name and key fields by checking collection/model definitions in the current app (look for "collectionName:" and date fields like date_created/date_completed/createdAt). Do not invent collection names.',
|
|
446
501
|
'- For creation-date questions when both date_created and createdAt exist, match both with $or so results are not missed.',
|
|
447
502
|
'- When grouping by fields that can be arrays (drivers, deliveries, routes, chemicals), $unwind first and group by both id and name when available.',
|
|
448
|
-
'- Use
|
|
503
|
+
'- Use REPORT_BUILDER_READ/REPORT_BUILDER_AGG only to produce summaries/snapshots/health checks (not raw dumps) when permitted.',
|
|
449
504
|
'- If the user explicitly asks for IDs, set options.includeIds: true.',
|
|
450
505
|
'- If a data question returns zero results, verify the collection/date field with a tiny read (limit 1-5) or a date field fallback before concluding there is no data.',
|
|
451
|
-
'- Keep responses concise and use the configured reasoning effort level (default low).'
|
|
506
|
+
'- Keep responses concise and use the configured reasoning effort level (default low).',
|
|
507
|
+
'',
|
|
508
|
+
AI_ASSISTANT_REPORT_BUILDER_EXPERT_PLAYBOOK
|
|
509
|
+
].join('\n');
|
|
510
|
+
var AI_ASSISTANT_PLANNER_SYSTEM_PROMPT = [
|
|
511
|
+
'You are ResolveIO Assistant Planner. Your job is to produce a permissions-aware execution plan for the user\'s request.',
|
|
512
|
+
'',
|
|
513
|
+
'HARD RULES (must follow):',
|
|
514
|
+
'1) PERMISSIONS FIRST: Determine access tier before planning anything.',
|
|
515
|
+
' - If user.roles.super_admin === true: tier = "super_admin" (full access).',
|
|
516
|
+
' - Else if user.other.id_customer exists (non-empty): tier = "customer_portal" (restrict to that customer\'s data + their views).',
|
|
517
|
+
' - Else: tier = "client_user" (restrict to their views; client-scoped data).',
|
|
518
|
+
'',
|
|
519
|
+
'2) NEVER suggest pages/routes the user cannot access.',
|
|
520
|
+
' - Only recommend routes that match their allowed views.',
|
|
521
|
+
' - If route inventory is provided (KnownRoutes), choose from it. Do not invent new routes.',
|
|
522
|
+
' - If no allowed route exists, propose the closest allowed route OR tell them they need access.',
|
|
523
|
+
'',
|
|
524
|
+
'3) DATA ACCESS MUST MATCH PERMISSIONS:',
|
|
525
|
+
' - super_admin: no scope restriction required.',
|
|
526
|
+
' - customer_portal: apply customer scope (id_customer or other.id_customer) to all data plans.',
|
|
527
|
+
' - client_user: apply client scope (id_client) to all data plans.',
|
|
528
|
+
' - Never propose querying blocked/sensitive collections if the user lacks permission.',
|
|
529
|
+
'',
|
|
530
|
+
'4) PERMISSION MATCHING:',
|
|
531
|
+
' - Do NOT hardcode invoice access to "/report/invoice".',
|
|
532
|
+
' - For invoice-related data or navigation, permission is satisfied if ANY user view contains "invoice" case-insensitive.',
|
|
533
|
+
' (General rule: for an entity token X, permission is satisfied if any view contains X case-insensitive.)',
|
|
534
|
+
' - If permission checks are ambiguous, choose the safest restriction and explain.',
|
|
535
|
+
'',
|
|
536
|
+
'5) CLASSIFY THE REQUEST:',
|
|
537
|
+
' - type = "navigation" if user asks how/where to do something in the app.',
|
|
538
|
+
' - type = "data" if user asks for totals, lists, breakdowns, counts, reports, "last N", "by month", etc.',
|
|
539
|
+
' - type = "program_explain" if user asks how the system works (features/process).',
|
|
540
|
+
' - type = "mixed" if both navigation + data are clearly requested.',
|
|
541
|
+
'',
|
|
542
|
+
'6) OUTPUT FORMAT:',
|
|
543
|
+
' - Return ONLY a single JSON object (no markdown, no extra text).',
|
|
544
|
+
' - The JSON must match the schema provided in the user prompt.',
|
|
545
|
+
' - Be explicit and actionable. Prefer more guidance over less.',
|
|
546
|
+
' - If data is requested: output a dataPlan but DO NOT write a raw Mongo pipeline. Your output is a QueryPlan that a deterministic builder will convert.',
|
|
547
|
+
'',
|
|
548
|
+
'7) USER-TONE PLANNING:',
|
|
549
|
+
' - If user name is available, personalize greeting.',
|
|
550
|
+
' - If group names are available, reference them in the plan (e.g., "Drivers group").',
|
|
551
|
+
' - Always propose next steps from where they are (currentRoute if provided).',
|
|
552
|
+
' - End plan with 1-2 engaging follow-up questions the assistant can ask the user.',
|
|
553
|
+
'',
|
|
554
|
+
'8) DO NOT run shell commands or read repo files in this planning step. Use only the provided context.'
|
|
555
|
+
].join('\n');
|
|
556
|
+
var AI_ASSISTANT_PLANNER_USER_PROMPT_TEMPLATE = [
|
|
557
|
+
'You MUST return JSON only, matching this schema:',
|
|
558
|
+
'',
|
|
559
|
+
'{',
|
|
560
|
+
' "access": {',
|
|
561
|
+
' "tier": "super_admin" | "customer_portal" | "client_user",',
|
|
562
|
+
' "isSuperAdmin": boolean,',
|
|
563
|
+
' "customerId": string | null,',
|
|
564
|
+
' "clientId": string | null,',
|
|
565
|
+
' "userDisplayName": string | null,',
|
|
566
|
+
' "groupNames": string[],',
|
|
567
|
+
' "allowedViews": string[],',
|
|
568
|
+
' "permissionRules": {',
|
|
569
|
+
' "entityPermissionMatch": "views_contains_token_case_insensitive",',
|
|
570
|
+
' "invoicePermissionRegex": "invoice"',
|
|
571
|
+
' }',
|
|
572
|
+
' },',
|
|
573
|
+
' "intent": {',
|
|
574
|
+
' "type": "navigation" | "data" | "program_explain" | "mixed",',
|
|
575
|
+
' "summary": string,',
|
|
576
|
+
' "confidence": number',
|
|
577
|
+
' },',
|
|
578
|
+
' "navigationPlan": {',
|
|
579
|
+
' "startingRoute": string | null,',
|
|
580
|
+
' "recommendedRoutes": Array<{',
|
|
581
|
+
' "route": string,',
|
|
582
|
+
' "reason": string,',
|
|
583
|
+
' "requiresViewToken": string',
|
|
584
|
+
' }>,',
|
|
585
|
+
' "stepByStep": string[],',
|
|
586
|
+
' "deepLinks": Array<{',
|
|
587
|
+
' "label": string,',
|
|
588
|
+
' "route": string,',
|
|
589
|
+
' "reason": string',
|
|
590
|
+
' }>',
|
|
591
|
+
' },',
|
|
592
|
+
' "dataPlan": {',
|
|
593
|
+
' "shouldFetchData": boolean,',
|
|
594
|
+
' "permissionCheck": {',
|
|
595
|
+
' "requiredViewToken": string | null,',
|
|
596
|
+
' "allowed": boolean,',
|
|
597
|
+
' "reason": string',
|
|
598
|
+
' },',
|
|
599
|
+
' "entity": string | null,',
|
|
600
|
+
' "metric": string | null,',
|
|
601
|
+
' "timeRange": {',
|
|
602
|
+
' "type": "last_n_months" | "custom" | "all_time" | null,',
|
|
603
|
+
' "n": number | null,',
|
|
604
|
+
' "startDateISO": string | null,',
|
|
605
|
+
' "endDateISO": string | null,',
|
|
606
|
+
' "grain": "day" | "week" | "month" | "quarter" | null',
|
|
607
|
+
' },',
|
|
608
|
+
' "scoping": {',
|
|
609
|
+
' "applyClientScope": boolean,',
|
|
610
|
+
' "applyCustomerScope": boolean,',
|
|
611
|
+
' "customerScopeField": "id_customer" | "other.id_customer" | null,',
|
|
612
|
+
' "clientScopeField": "id_client" | null',
|
|
613
|
+
' },',
|
|
614
|
+
' "queryPlan": {',
|
|
615
|
+
' "preferredCollections": string[],',
|
|
616
|
+
' "fallbackCollections": string[],',
|
|
617
|
+
' "dateFieldPreferences": string[],',
|
|
618
|
+
' "amountFieldPreferences": string[],',
|
|
619
|
+
' "statusStrategy": "none" | "paid_like" | "open_like" | "closed_like",',
|
|
620
|
+
' "groupBy": string | null,',
|
|
621
|
+
' "sort": string | null,',
|
|
622
|
+
' "limit": number | null',
|
|
623
|
+
' },',
|
|
624
|
+
' "validationChecklist": string[]',
|
|
625
|
+
' },',
|
|
626
|
+
' "assistantResponsePlan": {',
|
|
627
|
+
' "greeting": string,',
|
|
628
|
+
' "whatINeedToSayFirst": string,',
|
|
629
|
+
' "responseMustInclude": string[],',
|
|
630
|
+
' "followUpQuestions": string[]',
|
|
631
|
+
' }',
|
|
632
|
+
'}',
|
|
633
|
+
'',
|
|
634
|
+
'Now produce a plan for the following request + context.',
|
|
635
|
+
'',
|
|
636
|
+
'Today (ISO): {{today_iso}}',
|
|
637
|
+
'User request: {{user_message}}',
|
|
638
|
+
'',
|
|
639
|
+
'Current route (may be null): {{current_route}}',
|
|
640
|
+
'Known routes (may be empty): {{known_routes_json_array}}',
|
|
641
|
+
'',
|
|
642
|
+
'User object (sanitized): {{user_json}}',
|
|
643
|
+
'Notes:',
|
|
644
|
+
'- user.roles.super_admin may exist',
|
|
645
|
+
'- user.roles.groups may include { name, views: [] }',
|
|
646
|
+
'- user.roles.miscs may include views strings',
|
|
647
|
+
'- user.other.id_customer may exist for customer portal users',
|
|
648
|
+
'',
|
|
649
|
+
'Collection hints (may be empty): {{collection_hints_json_array}}',
|
|
650
|
+
'Field hints (may be empty): {{field_hints_json_array}}',
|
|
651
|
+
'',
|
|
652
|
+
'Important:',
|
|
653
|
+
'- If invoice-related, permission is satisfied if ANY allowed view contains "invoice" case-insensitive.',
|
|
654
|
+
'- Do not output raw Mongo pipelines. Output a QueryPlan + validation checklist only.',
|
|
655
|
+
'- Navigation steps must only reference routes that match allowed views (or known routes if provided).'
|
|
452
656
|
].join('\n');
|
|
453
657
|
var AI_FORM_PATCH_SYSTEM_PROMPT = [
|
|
454
658
|
'You are the ResolveIO form patch assistant.',
|
|
@@ -838,6 +1042,42 @@ function loadAiTerminalMethods(methodManager) {
|
|
|
838
1042
|
});
|
|
839
1043
|
}
|
|
840
1044
|
},
|
|
1045
|
+
aiAssistantReportBuilderRead: {
|
|
1046
|
+
check: new simpl_schema_1.default({
|
|
1047
|
+
payload: {
|
|
1048
|
+
type: Object,
|
|
1049
|
+
blackbox: true
|
|
1050
|
+
}
|
|
1051
|
+
}),
|
|
1052
|
+
function: function (payload) {
|
|
1053
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1054
|
+
return __generator(this, function (_a) {
|
|
1055
|
+
switch (_a.label) {
|
|
1056
|
+
case 0: return [4 /*yield*/, executeAiAssistantMongoRead(payload, this)];
|
|
1057
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
1058
|
+
}
|
|
1059
|
+
});
|
|
1060
|
+
});
|
|
1061
|
+
}
|
|
1062
|
+
},
|
|
1063
|
+
aiAssistantReportBuilderAggregate: {
|
|
1064
|
+
check: new simpl_schema_1.default({
|
|
1065
|
+
payload: {
|
|
1066
|
+
type: Object,
|
|
1067
|
+
blackbox: true
|
|
1068
|
+
}
|
|
1069
|
+
}),
|
|
1070
|
+
function: function (payload) {
|
|
1071
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1072
|
+
return __generator(this, function (_a) {
|
|
1073
|
+
switch (_a.label) {
|
|
1074
|
+
case 0: return [4 /*yield*/, executeAiAssistantMongoAggregate(payload, this)];
|
|
1075
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
1076
|
+
}
|
|
1077
|
+
});
|
|
1078
|
+
});
|
|
1079
|
+
}
|
|
1080
|
+
},
|
|
841
1081
|
aiCoderTerminalDeployTest: {
|
|
842
1082
|
check: new simpl_schema_1.default({
|
|
843
1083
|
id_conversation: {
|
|
@@ -1197,10 +1437,10 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1197
1437
|
insertResult = _d.sent();
|
|
1198
1438
|
assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
|
|
1199
1439
|
enqueueAssistantCodexRun(function () { return __awaiter(_this, void 0, void 0, function () {
|
|
1200
|
-
var runStart, steps, recordStep, progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, dataQuestion, lastDirective, toolResponseDebug, toolError, termHints, collectionHints, fieldHints, collectionTokenization, collectionRanking, collectionSelection, collectionOverride, collectionNames, timingBreakdown, contextRoute, contextMode, hintSeed, termExpansion, hintText, baseTokens, expandedTokens, baseWeights, expandedWeights, dbName, db, _a, routeHints, rankedCollections, hintCollections, assistantContext, prompt_1, workspaceRoot, codexConfig, runOptions, responseText, directiveText, directive, directivePrompt, directiveStart, forcedDirective,
|
|
1201
|
-
var
|
|
1202
|
-
return __generator(this, function (
|
|
1203
|
-
switch (
|
|
1440
|
+
var runStart, steps, recordStep, progressTracker, streamProgress, assistantContent, toolResult, assistantDebug, directiveSource, dataQuestion, lastDirective, toolResponseDebug, toolError, termHints, collectionHints, fieldHints, collectionTokenization, collectionRanking, collectionSelection, collectionOverride, collectionNames, plannerEnabled, plannerOutput, plannerRaw, timingBreakdown, contextRoute, contextMode, hintSeed, termExpansion, hintText, baseTokens, expandedTokens, baseWeights, expandedWeights, dbName, db, _a, routeHints, rankedCollections, hintCollections, assistantContext, prompt_1, workspaceRoot, codexConfig, runOptions, plannerPrompt, plannerStart, _b, intentType, shouldFetch, responseText, directiveText, directive, directivePrompt, directiveStart, forcedDirective, _c, initialStart, directivePrompt, forcedStart, forcedDirective, _d, requestedCollection, cleanedResponseText, effectiveDirective, toolRequest, toolStart, toolResponse, _e, toolPayload, followupPrompt, followupStart, followupText, _f, error_2, error_3, finishedAt, finalNow, finishedAt, codexMs, draftingMs, finalMetadata, finalAssistantDoc;
|
|
1441
|
+
var _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
|
|
1442
|
+
return __generator(this, function (_x) {
|
|
1443
|
+
switch (_x.label) {
|
|
1204
1444
|
case 0:
|
|
1205
1445
|
runStart = Date.now();
|
|
1206
1446
|
if (aiWorkerDebug) {
|
|
@@ -1241,19 +1481,23 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1241
1481
|
collectionSelection = null;
|
|
1242
1482
|
collectionOverride = null;
|
|
1243
1483
|
collectionNames = [];
|
|
1484
|
+
plannerEnabled = resolveAssistantPlannerEnabled();
|
|
1485
|
+
plannerOutput = null;
|
|
1486
|
+
plannerRaw = '';
|
|
1244
1487
|
timingBreakdown = {
|
|
1488
|
+
plannerMs: 0,
|
|
1245
1489
|
directiveMs: 0,
|
|
1246
1490
|
initialResponseMs: 0,
|
|
1247
1491
|
forcedDirectiveMs: 0,
|
|
1248
1492
|
toolMs: 0,
|
|
1249
1493
|
followupMs: 0
|
|
1250
1494
|
};
|
|
1251
|
-
contextRoute = normalizeOptionalString((
|
|
1252
|
-
contextMode = normalizeOptionalString((
|
|
1495
|
+
contextRoute = normalizeOptionalString((_g = input === null || input === void 0 ? void 0 : input.context) === null || _g === void 0 ? void 0 : _g.route);
|
|
1496
|
+
contextMode = normalizeOptionalString((_h = input === null || input === void 0 ? void 0 : input.context) === null || _h === void 0 ? void 0 : _h.mode);
|
|
1253
1497
|
recordStep('Queued', { requestId: requestId || undefined });
|
|
1254
|
-
|
|
1498
|
+
_x.label = 1;
|
|
1255
1499
|
case 1:
|
|
1256
|
-
|
|
1500
|
+
_x.trys.push([1, 35, 36, 37]);
|
|
1257
1501
|
hintSeed = [message, contextRoute].filter(Boolean).join(' ');
|
|
1258
1502
|
termExpansion = expandAssistantTermSynonyms(hintSeed);
|
|
1259
1503
|
hintText = termExpansion.expanded || hintSeed;
|
|
@@ -1274,19 +1518,19 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1274
1518
|
recordStep('Planning: term expansion', {
|
|
1275
1519
|
termMatches: termExpansion.matches.length ? termExpansion.matches : undefined
|
|
1276
1520
|
});
|
|
1277
|
-
|
|
1521
|
+
_x.label = 2;
|
|
1278
1522
|
case 2:
|
|
1279
|
-
|
|
1523
|
+
_x.trys.push([2, 4, , 5]);
|
|
1280
1524
|
dbName = resolveAssistantDatabaseName(undefined, input.mongo);
|
|
1281
1525
|
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
1282
1526
|
return [4 /*yield*/, listAssistantCollections(db, dbName)];
|
|
1283
1527
|
case 3:
|
|
1284
|
-
collectionNames =
|
|
1528
|
+
collectionNames = _x.sent();
|
|
1285
1529
|
collectionHints = resolveCollectionHintsFromTokens(expandedTokens, collectionNames, 5);
|
|
1286
1530
|
collectionRanking = buildCollectionRankingDebugFromTokens(expandedTokens, collectionNames, 8);
|
|
1287
1531
|
return [3 /*break*/, 5];
|
|
1288
1532
|
case 4:
|
|
1289
|
-
_a =
|
|
1533
|
+
_a = _x.sent();
|
|
1290
1534
|
collectionHints = [];
|
|
1291
1535
|
collectionRanking = collectionRanking || ((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens)
|
|
1292
1536
|
? buildCollectionRankingDebugFromTokens(collectionTokenization.expandedTokens || [], [], 0)
|
|
@@ -1321,7 +1565,7 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1321
1565
|
prompt_1 = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
|
|
1322
1566
|
return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
|
|
1323
1567
|
case 6:
|
|
1324
|
-
workspaceRoot =
|
|
1568
|
+
workspaceRoot = _x.sent();
|
|
1325
1569
|
codexConfig = resolveCodexSettings();
|
|
1326
1570
|
runOptions = {
|
|
1327
1571
|
timeoutMs: resolveCodexTimeoutMs(),
|
|
@@ -1336,95 +1580,132 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1336
1580
|
approvalPolicy: 'never'
|
|
1337
1581
|
}
|
|
1338
1582
|
};
|
|
1583
|
+
if (!plannerEnabled) return [3 /*break*/, 11];
|
|
1584
|
+
recordStep('Planning: planner prompt');
|
|
1585
|
+
plannerPrompt = buildAssistantPlannerPrompt({
|
|
1586
|
+
message: message,
|
|
1587
|
+
attachmentText: attachmentData.promptText,
|
|
1588
|
+
contextRoute: contextRoute,
|
|
1589
|
+
knownRoutes: resolveAssistantPlannerKnownRoutes(),
|
|
1590
|
+
user: user,
|
|
1591
|
+
collectionHints: collectionHints,
|
|
1592
|
+
fieldHints: fieldHints,
|
|
1593
|
+
inputClientId: input.id_client
|
|
1594
|
+
});
|
|
1595
|
+
_x.label = 7;
|
|
1596
|
+
case 7:
|
|
1597
|
+
_x.trys.push([7, 9, , 10]);
|
|
1598
|
+
plannerStart = Date.now();
|
|
1599
|
+
return [4 /*yield*/, runCodexInWorkerThread(plannerPrompt, runOptions, codexConfig, streamProgress)];
|
|
1600
|
+
case 8:
|
|
1601
|
+
plannerRaw = _x.sent();
|
|
1602
|
+
timingBreakdown.plannerMs = Date.now() - plannerStart;
|
|
1603
|
+
plannerOutput = parseJsonObject(plannerRaw);
|
|
1604
|
+
recordStep('Planning: planner result', { parsed: !!plannerOutput });
|
|
1605
|
+
return [3 /*break*/, 10];
|
|
1606
|
+
case 9:
|
|
1607
|
+
_b = _x.sent();
|
|
1608
|
+
recordStep('Planning: planner result', { parsed: false });
|
|
1609
|
+
return [3 /*break*/, 10];
|
|
1610
|
+
case 10:
|
|
1611
|
+
if (plannerOutput) {
|
|
1612
|
+
intentType = normalizeOptionalString((_j = plannerOutput === null || plannerOutput === void 0 ? void 0 : plannerOutput.intent) === null || _j === void 0 ? void 0 : _j.type).toLowerCase();
|
|
1613
|
+
shouldFetch = ((_k = plannerOutput === null || plannerOutput === void 0 ? void 0 : plannerOutput.dataPlan) === null || _k === void 0 ? void 0 : _k.shouldFetchData) === true;
|
|
1614
|
+
if (shouldFetch || intentType === 'data' || intentType === 'mixed') {
|
|
1615
|
+
dataQuestion = true;
|
|
1616
|
+
}
|
|
1617
|
+
}
|
|
1618
|
+
_x.label = 11;
|
|
1619
|
+
case 11:
|
|
1339
1620
|
responseText = '';
|
|
1340
1621
|
directiveText = '';
|
|
1341
1622
|
directive = null;
|
|
1342
|
-
if (!dataQuestion) return [3 /*break*/,
|
|
1623
|
+
if (!dataQuestion) return [3 /*break*/, 15];
|
|
1343
1624
|
recordStep('Directive: determine tool', { type: 'data-question' });
|
|
1344
1625
|
directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
|
|
1345
|
-
|
|
1346
|
-
case
|
|
1347
|
-
|
|
1626
|
+
_x.label = 12;
|
|
1627
|
+
case 12:
|
|
1628
|
+
_x.trys.push([12, 14, , 15]);
|
|
1348
1629
|
directiveStart = Date.now();
|
|
1349
1630
|
return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
|
|
1350
|
-
case
|
|
1351
|
-
directiveText =
|
|
1631
|
+
case 13:
|
|
1632
|
+
directiveText = _x.sent();
|
|
1352
1633
|
timingBreakdown.directiveMs = Date.now() - directiveStart;
|
|
1353
1634
|
forcedDirective = extractAssistantMongoDirective(directiveText);
|
|
1354
1635
|
if (forcedDirective) {
|
|
1355
1636
|
directive = forcedDirective;
|
|
1356
1637
|
directiveSource = 'model';
|
|
1357
1638
|
lastDirective = forcedDirective;
|
|
1358
|
-
collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((
|
|
1639
|
+
collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((_l = directive.payload) === null || _l === void 0 ? void 0 : _l.collection) || '');
|
|
1359
1640
|
recordStep('Directive resolved', {
|
|
1360
1641
|
source: directiveSource,
|
|
1361
1642
|
type: directive.type,
|
|
1362
|
-
collection: normalizeOptionalString((
|
|
1363
|
-
permissionView: normalizeOptionalString((
|
|
1643
|
+
collection: normalizeOptionalString((_m = directive.payload) === null || _m === void 0 ? void 0 : _m.collection) || undefined,
|
|
1644
|
+
permissionView: normalizeOptionalString((_o = directive.payload) === null || _o === void 0 ? void 0 : _o.permissionView) || undefined
|
|
1364
1645
|
});
|
|
1365
1646
|
}
|
|
1366
|
-
return [3 /*break*/,
|
|
1367
|
-
case
|
|
1368
|
-
|
|
1369
|
-
return [3 /*break*/,
|
|
1370
|
-
case
|
|
1371
|
-
if (!!directive) return [3 /*break*/,
|
|
1647
|
+
return [3 /*break*/, 15];
|
|
1648
|
+
case 14:
|
|
1649
|
+
_c = _x.sent();
|
|
1650
|
+
return [3 /*break*/, 15];
|
|
1651
|
+
case 15:
|
|
1652
|
+
if (!!directive) return [3 /*break*/, 17];
|
|
1372
1653
|
recordStep('Response: draft initial answer', { mode: 'full' });
|
|
1373
1654
|
initialStart = Date.now();
|
|
1374
1655
|
return [4 /*yield*/, runCodexInWorkerThread(prompt_1, runOptions, codexConfig, streamProgress)];
|
|
1375
|
-
case
|
|
1376
|
-
responseText =
|
|
1656
|
+
case 16:
|
|
1657
|
+
responseText = _x.sent();
|
|
1377
1658
|
timingBreakdown.initialResponseMs = Date.now() - initialStart;
|
|
1378
1659
|
directive = extractAssistantMongoDirective(responseText);
|
|
1379
1660
|
if (directive) {
|
|
1380
1661
|
directiveSource = 'model';
|
|
1381
1662
|
lastDirective = directive;
|
|
1382
|
-
collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((
|
|
1663
|
+
collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((_p = directive.payload) === null || _p === void 0 ? void 0 : _p.collection) || '');
|
|
1383
1664
|
recordStep('Directive resolved', {
|
|
1384
1665
|
source: directiveSource,
|
|
1385
1666
|
type: directive.type,
|
|
1386
|
-
collection: normalizeOptionalString((
|
|
1387
|
-
permissionView: normalizeOptionalString((
|
|
1667
|
+
collection: normalizeOptionalString((_q = directive.payload) === null || _q === void 0 ? void 0 : _q.collection) || undefined,
|
|
1668
|
+
permissionView: normalizeOptionalString((_r = directive.payload) === null || _r === void 0 ? void 0 : _r.permissionView) || undefined
|
|
1388
1669
|
});
|
|
1389
1670
|
}
|
|
1390
|
-
|
|
1391
|
-
case
|
|
1392
|
-
if (!(!directive && dataQuestion)) return [3 /*break*/,
|
|
1671
|
+
_x.label = 17;
|
|
1672
|
+
case 17:
|
|
1673
|
+
if (!(!directive && dataQuestion)) return [3 /*break*/, 21];
|
|
1393
1674
|
recordStep('Directive: forced retry', { mode: 'directive-only' });
|
|
1394
1675
|
directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
|
|
1395
|
-
|
|
1396
|
-
case
|
|
1397
|
-
|
|
1676
|
+
_x.label = 18;
|
|
1677
|
+
case 18:
|
|
1678
|
+
_x.trys.push([18, 20, , 21]);
|
|
1398
1679
|
forcedStart = Date.now();
|
|
1399
1680
|
return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
|
|
1400
|
-
case
|
|
1401
|
-
directiveText =
|
|
1681
|
+
case 19:
|
|
1682
|
+
directiveText = _x.sent();
|
|
1402
1683
|
timingBreakdown.forcedDirectiveMs = Date.now() - forcedStart;
|
|
1403
1684
|
forcedDirective = extractAssistantMongoDirective(directiveText);
|
|
1404
1685
|
if (forcedDirective) {
|
|
1405
1686
|
directive = forcedDirective;
|
|
1406
1687
|
directiveSource = 'forced';
|
|
1407
1688
|
lastDirective = forcedDirective;
|
|
1408
|
-
collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((
|
|
1689
|
+
collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((_s = directive.payload) === null || _s === void 0 ? void 0 : _s.collection) || '');
|
|
1409
1690
|
recordStep('Directive resolved', {
|
|
1410
1691
|
source: directiveSource,
|
|
1411
1692
|
type: directive.type,
|
|
1412
|
-
collection: normalizeOptionalString((
|
|
1413
|
-
permissionView: normalizeOptionalString((
|
|
1693
|
+
collection: normalizeOptionalString((_t = directive.payload) === null || _t === void 0 ? void 0 : _t.collection) || undefined,
|
|
1694
|
+
permissionView: normalizeOptionalString((_u = directive.payload) === null || _u === void 0 ? void 0 : _u.permissionView) || undefined
|
|
1414
1695
|
});
|
|
1415
1696
|
}
|
|
1416
|
-
return [3 /*break*/,
|
|
1417
|
-
case
|
|
1418
|
-
|
|
1419
|
-
return [3 /*break*/,
|
|
1420
|
-
case
|
|
1697
|
+
return [3 /*break*/, 21];
|
|
1698
|
+
case 20:
|
|
1699
|
+
_d = _x.sent();
|
|
1700
|
+
return [3 /*break*/, 21];
|
|
1701
|
+
case 21:
|
|
1421
1702
|
if (directive) {
|
|
1422
|
-
requestedCollection = normalizeOptionalString((
|
|
1703
|
+
requestedCollection = normalizeOptionalString((_v = directive.payload) === null || _v === void 0 ? void 0 : _v.collection);
|
|
1423
1704
|
collectionOverride = resolveCollectionOverrideWithContext({
|
|
1424
1705
|
message: message,
|
|
1425
1706
|
collectionRanking: collectionRanking,
|
|
1426
1707
|
requestedCollection: requestedCollection,
|
|
1427
|
-
permissionView: normalizeOptionalString((
|
|
1708
|
+
permissionView: normalizeOptionalString((_w = directive.payload) === null || _w === void 0 ? void 0 : _w.permissionView) || contextRoute,
|
|
1428
1709
|
collectionNames: collectionNames
|
|
1429
1710
|
});
|
|
1430
1711
|
if (collectionOverride) {
|
|
@@ -1440,7 +1721,7 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1440
1721
|
if (cleanedResponseText) {
|
|
1441
1722
|
assistantContent = sanitizeAssistantResponse(cleanedResponseText);
|
|
1442
1723
|
}
|
|
1443
|
-
if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/,
|
|
1724
|
+
if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 33];
|
|
1444
1725
|
effectiveDirective = collectionOverride
|
|
1445
1726
|
? __assign(__assign({}, directive), { payload: __assign(__assign({}, (directive.payload || {})), { collection: collectionOverride.to }) }) : directive;
|
|
1446
1727
|
toolRequest = buildAssistantToolRequest(effectiveDirective, input);
|
|
@@ -1450,21 +1731,21 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1450
1731
|
collection: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.collection) || undefined,
|
|
1451
1732
|
permissionView: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.permissionView) || undefined
|
|
1452
1733
|
});
|
|
1453
|
-
|
|
1454
|
-
case
|
|
1455
|
-
|
|
1734
|
+
_x.label = 22;
|
|
1735
|
+
case 22:
|
|
1736
|
+
_x.trys.push([22, 31, , 32]);
|
|
1456
1737
|
toolStart = Date.now();
|
|
1457
|
-
if (!(effectiveDirective.type === 'aggregate')) return [3 /*break*/,
|
|
1458
|
-
return [4 /*yield*/,
|
|
1459
|
-
case
|
|
1460
|
-
|
|
1461
|
-
return [3 /*break*/,
|
|
1462
|
-
case
|
|
1463
|
-
case
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
case
|
|
1467
|
-
toolResponse =
|
|
1738
|
+
if (!(effectiveDirective.type === 'aggregate')) return [3 /*break*/, 24];
|
|
1739
|
+
return [4 /*yield*/, executeAiAssistantReportBuilderAggregate(toolRequest, context)];
|
|
1740
|
+
case 23:
|
|
1741
|
+
_e = _x.sent();
|
|
1742
|
+
return [3 /*break*/, 26];
|
|
1743
|
+
case 24: return [4 /*yield*/, executeAiAssistantReportBuilderRead(toolRequest, context)];
|
|
1744
|
+
case 25:
|
|
1745
|
+
_e = _x.sent();
|
|
1746
|
+
_x.label = 26;
|
|
1747
|
+
case 26:
|
|
1748
|
+
toolResponse = _e;
|
|
1468
1749
|
timingBreakdown.toolMs = Date.now() - toolStart;
|
|
1469
1750
|
toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
|
|
1470
1751
|
? toolResponse.debug
|
|
@@ -1479,42 +1760,42 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1479
1760
|
progressTracker.push('Drafting response');
|
|
1480
1761
|
recordStep('Drafting response');
|
|
1481
1762
|
followupPrompt = buildAssistantCodexToolFollowupPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext, toolPayload.prompt);
|
|
1482
|
-
|
|
1483
|
-
case
|
|
1484
|
-
|
|
1763
|
+
_x.label = 27;
|
|
1764
|
+
case 27:
|
|
1765
|
+
_x.trys.push([27, 29, , 30]);
|
|
1485
1766
|
followupStart = Date.now();
|
|
1486
1767
|
return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
|
|
1487
|
-
case
|
|
1488
|
-
followupText =
|
|
1768
|
+
case 28:
|
|
1769
|
+
followupText = _x.sent();
|
|
1489
1770
|
timingBreakdown.followupMs = Date.now() - followupStart;
|
|
1490
1771
|
assistantContent = sanitizeAssistantResponse(followupText);
|
|
1491
1772
|
assistantContent = applyAssistantDisplayTableToResponse(assistantContent, toolPayload.result.output.display);
|
|
1492
|
-
return [3 /*break*/,
|
|
1493
|
-
case
|
|
1494
|
-
|
|
1773
|
+
return [3 /*break*/, 30];
|
|
1774
|
+
case 29:
|
|
1775
|
+
_f = _x.sent();
|
|
1495
1776
|
assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
|
|
1496
|
-
return [3 /*break*/,
|
|
1497
|
-
case
|
|
1498
|
-
case
|
|
1499
|
-
error_2 =
|
|
1777
|
+
return [3 /*break*/, 30];
|
|
1778
|
+
case 30: return [3 /*break*/, 32];
|
|
1779
|
+
case 31:
|
|
1780
|
+
error_2 = _x.sent();
|
|
1500
1781
|
assistantContent = buildAssistantToolErrorMessage(error_2, directive, toolRequest);
|
|
1501
1782
|
toolError = error_2;
|
|
1502
|
-
return [3 /*break*/,
|
|
1503
|
-
case
|
|
1504
|
-
case
|
|
1783
|
+
return [3 /*break*/, 32];
|
|
1784
|
+
case 32: return [3 /*break*/, 34];
|
|
1785
|
+
case 33:
|
|
1505
1786
|
progressTracker.push('Drafting response');
|
|
1506
1787
|
recordStep('Drafting response');
|
|
1507
|
-
|
|
1508
|
-
case
|
|
1509
|
-
case
|
|
1510
|
-
error_3 =
|
|
1788
|
+
_x.label = 34;
|
|
1789
|
+
case 34: return [3 /*break*/, 37];
|
|
1790
|
+
case 35:
|
|
1791
|
+
error_3 = _x.sent();
|
|
1511
1792
|
assistantContent = buildAssistantCodexErrorMessage(error_3);
|
|
1512
1793
|
recordStep('Error', { message: normalizeOptionalString(error_3 === null || error_3 === void 0 ? void 0 : error_3.message) || 'Unknown error' });
|
|
1513
|
-
return [3 /*break*/,
|
|
1514
|
-
case
|
|
1794
|
+
return [3 /*break*/, 37];
|
|
1795
|
+
case 36:
|
|
1515
1796
|
progressTracker.stop();
|
|
1516
1797
|
return [7 /*endfinally*/];
|
|
1517
|
-
case
|
|
1798
|
+
case 37:
|
|
1518
1799
|
if (!assistantContent) {
|
|
1519
1800
|
assistantContent = buildAssistantCodexErrorMessage(null);
|
|
1520
1801
|
}
|
|
@@ -1537,6 +1818,7 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1537
1818
|
if (isSuperAdmin) {
|
|
1538
1819
|
finishedAt = Date.now();
|
|
1539
1820
|
codexMs = timingBreakdown.directiveMs
|
|
1821
|
+
+ timingBreakdown.plannerMs
|
|
1540
1822
|
+ timingBreakdown.initialResponseMs
|
|
1541
1823
|
+ timingBreakdown.forcedDirectiveMs
|
|
1542
1824
|
+ timingBreakdown.followupMs;
|
|
@@ -1560,7 +1842,15 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1560
1842
|
collectionTokenization: collectionTokenization || undefined,
|
|
1561
1843
|
collectionRanking: collectionRanking || undefined,
|
|
1562
1844
|
collectionSelection: collectionSelection || undefined,
|
|
1563
|
-
collectionOverride: collectionOverride || undefined
|
|
1845
|
+
collectionOverride: collectionOverride || undefined,
|
|
1846
|
+
planner: plannerEnabled ? {
|
|
1847
|
+
enabled: true,
|
|
1848
|
+
parsed: !!plannerOutput,
|
|
1849
|
+
output: plannerOutput || undefined,
|
|
1850
|
+
raw: !plannerOutput && plannerRaw
|
|
1851
|
+
? plannerRaw.slice(0, AI_ASSISTANT_PLANNER_DEBUG_MAX_CHARS)
|
|
1852
|
+
: undefined
|
|
1853
|
+
} : undefined
|
|
1564
1854
|
},
|
|
1565
1855
|
timings: {
|
|
1566
1856
|
startedAt: new Date(runStart).toISOString(),
|
|
@@ -1569,6 +1859,7 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1569
1859
|
codexMs: codexMs,
|
|
1570
1860
|
draftingMs: draftingMs,
|
|
1571
1861
|
toolMs: timingBreakdown.toolMs,
|
|
1862
|
+
plannerMs: timingBreakdown.plannerMs,
|
|
1572
1863
|
directiveMs: timingBreakdown.directiveMs,
|
|
1573
1864
|
initialResponseMs: timingBreakdown.initialResponseMs,
|
|
1574
1865
|
forcedDirectiveMs: timingBreakdown.forcedDirectiveMs,
|
|
@@ -1579,7 +1870,7 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1579
1870
|
}
|
|
1580
1871
|
finalMetadata = __assign(__assign(__assign({ model: resolveCodexModel() }, (requestId ? { request_id: requestId } : {})), (toolResult ? { tool_result: toolResult } : {})), (assistantDebug ? { debug: assistantDebug } : {}));
|
|
1581
1872
|
finalAssistantDoc = __assign(__assign({}, assistantDoc), { _id: assistantMessageId, content: assistantContent, metadata: finalMetadata, updatedAt: finalNow });
|
|
1582
|
-
if (!assistantMessageId) return [3 /*break*/,
|
|
1873
|
+
if (!assistantMessageId) return [3 /*break*/, 39];
|
|
1583
1874
|
return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: assistantMessageId }, {
|
|
1584
1875
|
$set: {
|
|
1585
1876
|
content: assistantContent,
|
|
@@ -1587,18 +1878,18 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1587
1878
|
updatedAt: finalNow
|
|
1588
1879
|
}
|
|
1589
1880
|
})];
|
|
1590
|
-
case
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
case
|
|
1594
|
-
case
|
|
1595
|
-
|
|
1596
|
-
if (!(input.delete_files_after_run !== false)) return [3 /*break*/,
|
|
1881
|
+
case 38:
|
|
1882
|
+
_x.sent();
|
|
1883
|
+
_x.label = 39;
|
|
1884
|
+
case 39: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
|
|
1885
|
+
case 40:
|
|
1886
|
+
_x.sent();
|
|
1887
|
+
if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 42];
|
|
1597
1888
|
return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
|
|
1598
|
-
case
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
case
|
|
1889
|
+
case 41:
|
|
1890
|
+
_x.sent();
|
|
1891
|
+
_x.label = 42;
|
|
1892
|
+
case 42: return [2 /*return*/, finalAssistantDoc];
|
|
1602
1893
|
}
|
|
1603
1894
|
});
|
|
1604
1895
|
}); });
|
|
@@ -1609,9 +1900,29 @@ function executeAiAssistantCodexRun(payload, context) {
|
|
|
1609
1900
|
});
|
|
1610
1901
|
});
|
|
1611
1902
|
}
|
|
1903
|
+
function executeAiAssistantReportBuilderRead(payload, context) {
|
|
1904
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1905
|
+
return __generator(this, function (_a) {
|
|
1906
|
+
switch (_a.label) {
|
|
1907
|
+
case 0: return [4 /*yield*/, executeAiAssistantMongoRead(payload, context)];
|
|
1908
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
1909
|
+
}
|
|
1910
|
+
});
|
|
1911
|
+
});
|
|
1912
|
+
}
|
|
1913
|
+
function executeAiAssistantReportBuilderAggregate(payload, context) {
|
|
1914
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
1915
|
+
return __generator(this, function (_a) {
|
|
1916
|
+
switch (_a.label) {
|
|
1917
|
+
case 0: return [4 /*yield*/, executeAiAssistantMongoAggregate(payload, context)];
|
|
1918
|
+
case 1: return [2 /*return*/, _a.sent()];
|
|
1919
|
+
}
|
|
1920
|
+
});
|
|
1921
|
+
});
|
|
1922
|
+
}
|
|
1612
1923
|
function executeAiAssistantMongoRead(payload, context) {
|
|
1613
1924
|
return __awaiter(this, void 0, void 0, function () {
|
|
1614
|
-
var input, rawCollection, dbName, db, collectionResolution, collection, 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, _f, queryNoDate, _g, _h, _j, _k, allCollections, base, alt, altCount, _l, total, sanitizedDocuments, requestedFields, missingFields, _m, projectionAliases, expandedProjection, refreshedDocs, includeIds, fieldAliases, displayDocs, idLookupDisplay, priorityFields, display;
|
|
1925
|
+
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, _f, queryNoDate, _g, _h, _j, _k, allCollections, base, alt, altCount, _l, total, sanitizedDocuments, requestedFields, missingFields, _m, projectionAliases, expandedProjection, refreshedDocs, includeIds, fieldAliases, displayDocs, idLookupDisplay, priorityFields, display;
|
|
1615
1926
|
var _o, _p;
|
|
1616
1927
|
return __generator(this, function (_q) {
|
|
1617
1928
|
switch (_q.label) {
|
|
@@ -1619,7 +1930,7 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
1619
1930
|
input = payload || {};
|
|
1620
1931
|
rawCollection = normalizeOptionalString(input.collection);
|
|
1621
1932
|
if (!rawCollection) {
|
|
1622
|
-
throw new Error('AI assistant
|
|
1933
|
+
throw new Error('AI assistant report builder bridge: Collection is required.');
|
|
1623
1934
|
}
|
|
1624
1935
|
dbName = resolveAssistantDatabaseName(input.database, input.mongo);
|
|
1625
1936
|
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
@@ -1627,15 +1938,26 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
1627
1938
|
case 1:
|
|
1628
1939
|
collectionResolution = _q.sent();
|
|
1629
1940
|
collection = collectionResolution.name || rawCollection;
|
|
1941
|
+
bridgeCollection = resolveAssistantReportBuilderBridgeCollection(collection);
|
|
1942
|
+
if (bridgeCollection.fallbackFrom) {
|
|
1943
|
+
collection = bridgeCollection.collection;
|
|
1944
|
+
}
|
|
1630
1945
|
schemaFields = getCollectionSchemaFieldNames(collection);
|
|
1631
1946
|
return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
|
|
1632
1947
|
case 2:
|
|
1633
1948
|
_a = _q.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
|
|
1634
1949
|
if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
|
|
1635
|
-
throw new Error('AI assistant
|
|
1950
|
+
throw new Error('AI assistant report builder bridge: Access denied.');
|
|
1636
1951
|
}
|
|
1637
1952
|
customerId = normalizeOptionalString((_o = user === null || user === void 0 ? void 0 : user.other) === null || _o === void 0 ? void 0 : _o.id_customer);
|
|
1638
1953
|
fallbackMeta = {};
|
|
1954
|
+
if (bridgeCollection.fallbackFrom) {
|
|
1955
|
+
fallbackMeta.reportBuilderBridge = {
|
|
1956
|
+
from: bridgeCollection.fallbackFrom,
|
|
1957
|
+
to: collection,
|
|
1958
|
+
used: true
|
|
1959
|
+
};
|
|
1960
|
+
}
|
|
1639
1961
|
baseQuery = normalizeMongoQuery(input.query);
|
|
1640
1962
|
if (!isSuperAdmin && customerId) {
|
|
1641
1963
|
stripped = stripQueryFieldPathsDeepWithMeta(baseQuery, ['id_customer', 'other.id_customer']);
|
|
@@ -1649,7 +1971,7 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
1649
1971
|
if (!isSuperAdmin && (collection === 'users' || collection === 'user-versions')) {
|
|
1650
1972
|
userId = normalizeOptionalString(user === null || user === void 0 ? void 0 : user._id);
|
|
1651
1973
|
if (!userId) {
|
|
1652
|
-
throw new Error('AI assistant
|
|
1974
|
+
throw new Error('AI assistant report builder bridge: Access denied.');
|
|
1653
1975
|
}
|
|
1654
1976
|
baseQuery = {
|
|
1655
1977
|
$and: [baseQuery, { _id: userId }]
|
|
@@ -2062,6 +2384,7 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2062
2384
|
collectionMatched: collectionResolution.matched,
|
|
2063
2385
|
collectionCandidates: collectionResolution.candidates,
|
|
2064
2386
|
collectionScore: collectionResolution.score,
|
|
2387
|
+
bridge: 'report-builder',
|
|
2065
2388
|
database: dbName,
|
|
2066
2389
|
query: executedQuery,
|
|
2067
2390
|
options: normalized.findOptions,
|
|
@@ -2075,7 +2398,7 @@ function executeAiAssistantMongoRead(payload, context) {
|
|
|
2075
2398
|
}
|
|
2076
2399
|
function executeAiAssistantMongoAggregate(payload, context) {
|
|
2077
2400
|
return __awaiter(this, void 0, void 0, function () {
|
|
2078
|
-
var input, rawCollection, dbName, db, collectionResolution, collection, schemaFields, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, sanitizedPipeline, strippedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, dateField, aggregateOptions, documents, executedPipeline, probeDocs, fallback, fallbackPipeline, fallbackDocs, createdFallback, createdPipeline, createdDocs, expanded, expandedDocs, completionFallback, fallbackPipeline, fallbackDocs, completionExprFallback, fallbackPipeline, fallbackDocs, unwindFallback, shouldUnwind, _c, _d, fallbackPipeline, fallbackDocs, nameFallback, fallbackPipeline, fallbackDocs, _e, _loop_1, i, state_1, matchFields_1, _f, aliases, rewrittenPipeline, fallbackDocs, _loop_2, i, state_2, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, matchStages, diagnostics, combinedMatch, nameFields, dateFields, queryNoName, _g, queryNoDate, _h, _j, _k, _l, allCollections, base, alt, altCount, _m, sanitizedDocuments, includeIds, displayDocs, idLookupDisplay, display;
|
|
2401
|
+
var input, rawCollection, dbName, db, collectionResolution, collection, bridgeCollection, schemaFields, _a, user, isSuperAdmin, customerId, fallbackMeta, baseQuery, stripped, userId, normalizedClient, shouldScopeByClient, _b, clientScopedQuery, scopedQuery, normalizedPipeline, sanitizedPipeline, strippedPipeline, pipelineWithScope, normalizedOptions, limitedPipeline, dateField, aggregateOptions, documents, executedPipeline, probeDocs, fallback, fallbackPipeline, fallbackDocs, createdFallback, createdPipeline, createdDocs, expanded, expandedDocs, completionFallback, fallbackPipeline, fallbackDocs, completionExprFallback, fallbackPipeline, fallbackDocs, unwindFallback, shouldUnwind, _c, _d, fallbackPipeline, fallbackDocs, nameFallback, fallbackPipeline, fallbackDocs, _e, _loop_1, i, state_1, matchFields_1, _f, aliases, rewrittenPipeline, fallbackDocs, _loop_2, i, state_2, baseCollection, fallbackPayload, fallbackResult, existingFallbacks, matchStages, diagnostics, combinedMatch, nameFields, dateFields, queryNoName, _g, queryNoDate, _h, _j, _k, _l, allCollections, base, alt, altCount, _m, sanitizedDocuments, includeIds, displayDocs, idLookupDisplay, display;
|
|
2079
2402
|
var _o, _p;
|
|
2080
2403
|
return __generator(this, function (_q) {
|
|
2081
2404
|
switch (_q.label) {
|
|
@@ -2083,7 +2406,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
2083
2406
|
input = payload || {};
|
|
2084
2407
|
rawCollection = normalizeOptionalString(input.collection);
|
|
2085
2408
|
if (!rawCollection) {
|
|
2086
|
-
throw new Error('AI assistant
|
|
2409
|
+
throw new Error('AI assistant report builder bridge: Collection is required.');
|
|
2087
2410
|
}
|
|
2088
2411
|
dbName = resolveAssistantDatabaseName(input.database, input.mongo);
|
|
2089
2412
|
db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
|
|
@@ -2091,15 +2414,26 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
2091
2414
|
case 1:
|
|
2092
2415
|
collectionResolution = _q.sent();
|
|
2093
2416
|
collection = collectionResolution.name || rawCollection;
|
|
2417
|
+
bridgeCollection = resolveAssistantReportBuilderBridgeCollection(collection);
|
|
2418
|
+
if (bridgeCollection.fallbackFrom) {
|
|
2419
|
+
collection = bridgeCollection.collection;
|
|
2420
|
+
}
|
|
2094
2421
|
schemaFields = getCollectionSchemaFieldNames(collection);
|
|
2095
2422
|
return [4 /*yield*/, ensureAssistantReadAccess(context, input.permissionView, collection)];
|
|
2096
2423
|
case 2:
|
|
2097
2424
|
_a = _q.sent(), user = _a.user, isSuperAdmin = _a.isSuperAdmin;
|
|
2098
2425
|
if (!isSuperAdmin && AI_ASSISTANT_BLOCKED_COLLECTIONS.has(collection)) {
|
|
2099
|
-
throw new Error('AI assistant
|
|
2426
|
+
throw new Error('AI assistant report builder bridge: Access denied.');
|
|
2100
2427
|
}
|
|
2101
2428
|
customerId = normalizeOptionalString((_o = user === null || user === void 0 ? void 0 : user.other) === null || _o === void 0 ? void 0 : _o.id_customer);
|
|
2102
2429
|
fallbackMeta = {};
|
|
2430
|
+
if (bridgeCollection.fallbackFrom) {
|
|
2431
|
+
fallbackMeta.reportBuilderBridge = {
|
|
2432
|
+
from: bridgeCollection.fallbackFrom,
|
|
2433
|
+
to: collection,
|
|
2434
|
+
used: true
|
|
2435
|
+
};
|
|
2436
|
+
}
|
|
2103
2437
|
baseQuery = normalizeMongoQuery(input.query);
|
|
2104
2438
|
if (!isSuperAdmin && customerId) {
|
|
2105
2439
|
stripped = stripQueryFieldPathsDeepWithMeta(baseQuery, ['id_customer', 'other.id_customer']);
|
|
@@ -2113,7 +2447,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
2113
2447
|
if (!isSuperAdmin && (collection === 'users' || collection === 'user-versions')) {
|
|
2114
2448
|
userId = normalizeOptionalString(user === null || user === void 0 ? void 0 : user._id);
|
|
2115
2449
|
if (!userId) {
|
|
2116
|
-
throw new Error('AI assistant
|
|
2450
|
+
throw new Error('AI assistant report builder bridge: Access denied.');
|
|
2117
2451
|
}
|
|
2118
2452
|
baseQuery = {
|
|
2119
2453
|
$and: [baseQuery, { _id: userId }]
|
|
@@ -2150,7 +2484,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
2150
2484
|
limitedPipeline = applyAssistantAggregateLimit(pipelineWithScope, normalizedOptions.limit, normalizedOptions.maxLimit, normalizedOptions.defaultLimit);
|
|
2151
2485
|
dateField = findAggregateDateField(limitedPipeline);
|
|
2152
2486
|
if (containsForbiddenMongoOperators(limitedPipeline)) {
|
|
2153
|
-
throw new Error('AI assistant
|
|
2487
|
+
throw new Error('AI assistant report builder bridge: Pipeline contains restricted operators.');
|
|
2154
2488
|
}
|
|
2155
2489
|
aggregateOptions = __assign(__assign({}, normalizedOptions.aggregateOptions), { readPreference: AI_ASSISTANT_READ_PREFERENCE });
|
|
2156
2490
|
return [4 /*yield*/, db.collection(collection)
|
|
@@ -2678,6 +3012,7 @@ function executeAiAssistantMongoAggregate(payload, context) {
|
|
|
2678
3012
|
collectionMatched: collectionResolution.matched,
|
|
2679
3013
|
collectionCandidates: collectionResolution.candidates,
|
|
2680
3014
|
collectionScore: collectionResolution.score,
|
|
3015
|
+
bridge: 'report-builder',
|
|
2681
3016
|
database: dbName,
|
|
2682
3017
|
query: scopedQuery,
|
|
2683
3018
|
options: normalizedOptions.aggregateOptions,
|
|
@@ -2699,6 +3034,21 @@ function extractAssistantMongoDirective(content) {
|
|
|
2699
3034
|
lines.forEach(function (line, index) {
|
|
2700
3035
|
var normalized = line.trim().replace(/^[-*]+\s*/, '');
|
|
2701
3036
|
var upper = normalized.toUpperCase();
|
|
3037
|
+
if (upper.startsWith('REPORT_BUILDER_READ:')) {
|
|
3038
|
+
directiveIndexes.add(index);
|
|
3039
|
+
directiveIndex = index;
|
|
3040
|
+
directiveLine = normalized;
|
|
3041
|
+
directiveType = 'read';
|
|
3042
|
+
return;
|
|
3043
|
+
}
|
|
3044
|
+
if (upper.startsWith('REPORT_BUILDER_AGG:') || upper.startsWith('REPORT_BUILDER_AGGREGATE:')) {
|
|
3045
|
+
directiveIndexes.add(index);
|
|
3046
|
+
directiveIndex = index;
|
|
3047
|
+
directiveLine = normalized;
|
|
3048
|
+
directiveType = 'aggregate';
|
|
3049
|
+
return;
|
|
3050
|
+
}
|
|
3051
|
+
// Backward compatibility for existing assistant responses.
|
|
2702
3052
|
if (upper.startsWith('MONGO_READ:')) {
|
|
2703
3053
|
directiveIndexes.add(index);
|
|
2704
3054
|
directiveIndex = index;
|
|
@@ -2818,7 +3168,7 @@ function buildAssistantCodexToolFollowupPrompt(message, attachmentText, historyT
|
|
|
2818
3168
|
var trimmedHistory = normalizeOptionalString(historyText);
|
|
2819
3169
|
var historyBlock = trimmedHistory ? "\n\nConversation so far:\n".concat(trimmedHistory) : '';
|
|
2820
3170
|
var toolBlock = toolResultText ? "\n\nTool Result:\n".concat(toolResultText) : '';
|
|
2821
|
-
var instruction = '\n\nInstruction:\nNow answer the user. Do NOT output another
|
|
3171
|
+
var instruction = '\n\nInstruction:\nNow answer the user. Do NOT output another REPORT_BUILDER_* directive. Output plain Markdown. Summarize first, then include a Markdown table.';
|
|
2822
3172
|
return "System:\n".concat(AI_ASSISTANT_SYSTEM_PROMPT).concat(contextBlock).concat(historyBlock, "\n\nUser:\n").concat(message).concat(attachmentText || '').concat(toolBlock).concat(instruction).trim();
|
|
2823
3173
|
}
|
|
2824
3174
|
function buildAssistantToolFallbackResponse(result) {
|
|
@@ -2838,13 +3188,13 @@ function buildAssistantToolFallbackResponse(result) {
|
|
|
2838
3188
|
return lines.join('\n').trim();
|
|
2839
3189
|
}
|
|
2840
3190
|
function buildAssistantDebugPayload(params) {
|
|
2841
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3;
|
|
3191
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
|
|
2842
3192
|
var notes = [];
|
|
2843
3193
|
if (params.dataQuestion) {
|
|
2844
3194
|
notes.push('Detected a data request; tool call required.');
|
|
2845
3195
|
}
|
|
2846
3196
|
if (params.directiveSource === 'forced') {
|
|
2847
|
-
notes.push('Assistant response omitted a
|
|
3197
|
+
notes.push('Assistant response omitted a REPORT_BUILDER_* directive; ran a directive-only pass.');
|
|
2848
3198
|
}
|
|
2849
3199
|
if ((_a = params.collectionOverride) === null || _a === void 0 ? void 0 : _a.to) {
|
|
2850
3200
|
var from = params.collectionOverride.from ? "\"".concat(params.collectionOverride.from, "\"") : '(none)';
|
|
@@ -2939,19 +3289,24 @@ function buildAssistantDebugPayload(params) {
|
|
|
2939
3289
|
var collection = fallbackInfo.chemicalLookup.collection ? " in ".concat(fallbackInfo.chemicalLookup.collection) : '';
|
|
2940
3290
|
notes.push("Applied chemical lookup".concat(collection, "."));
|
|
2941
3291
|
}
|
|
2942
|
-
if ((_u = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.
|
|
3292
|
+
if ((_u = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.reportBuilderBridge) === null || _u === void 0 ? void 0 : _u.used) {
|
|
3293
|
+
var from = fallbackInfo.reportBuilderBridge.from || 'unknown';
|
|
3294
|
+
var to = fallbackInfo.reportBuilderBridge.to || 'unknown';
|
|
3295
|
+
notes.push("Report builder bridge collection: ".concat(from, " -> ").concat(to, "."));
|
|
3296
|
+
}
|
|
3297
|
+
if ((_v = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.reportFallback) === null || _v === void 0 ? void 0 : _v.used) {
|
|
2943
3298
|
var from = fallbackInfo.reportFallback.from || 'report';
|
|
2944
3299
|
var to = fallbackInfo.reportFallback.to || 'base';
|
|
2945
3300
|
notes.push("Report fallback: ".concat(from, " -> ").concat(to, "."));
|
|
2946
3301
|
}
|
|
2947
|
-
if ((
|
|
3302
|
+
if ((_w = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.idLookup) === null || _w === void 0 ? void 0 : _w.used) {
|
|
2948
3303
|
var field = fallbackInfo.idLookup.field || 'id';
|
|
2949
3304
|
var strategy = fallbackInfo.idLookup.strategy || 'lookup';
|
|
2950
3305
|
var collection = fallbackInfo.idLookup.collection ? " in ".concat(fallbackInfo.idLookup.collection) : '';
|
|
2951
3306
|
var detail = fallbackInfo.idLookup.nameField ? " via ".concat(fallbackInfo.idLookup.nameField) : '';
|
|
2952
3307
|
notes.push("Resolved ".concat(field, " by ").concat(strategy).concat(collection).concat(detail, "."));
|
|
2953
3308
|
}
|
|
2954
|
-
if ((
|
|
3309
|
+
if ((_x = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.idDisplayLookup) === null || _x === void 0 ? void 0 : _x.used) {
|
|
2955
3310
|
var lookups = Array.isArray(fallbackInfo.idDisplayLookup.lookups)
|
|
2956
3311
|
? fallbackInfo.idDisplayLookup.lookups
|
|
2957
3312
|
: [];
|
|
@@ -2962,7 +3317,7 @@ function buildAssistantDebugPayload(params) {
|
|
|
2962
3317
|
notes.push(summary ? "Resolved id lookups for display: ".concat(summary, ".") : 'Resolved id lookups for display.');
|
|
2963
3318
|
}
|
|
2964
3319
|
if (params.toolError) {
|
|
2965
|
-
var errorMessage = ((
|
|
3320
|
+
var errorMessage = ((_y = params.toolError) === null || _y === void 0 ? void 0 : _y.message) || String(params.toolError || '');
|
|
2966
3321
|
if (errorMessage) {
|
|
2967
3322
|
notes.push("Tool error: ".concat(errorMessage));
|
|
2968
3323
|
}
|
|
@@ -2983,13 +3338,13 @@ function buildAssistantDebugPayload(params) {
|
|
|
2983
3338
|
collectionResolved: resolvedCollection || undefined,
|
|
2984
3339
|
collectionMatched: matchedCollection,
|
|
2985
3340
|
collectionCandidates: candidateCollections.length ? candidateCollections : undefined,
|
|
2986
|
-
collectionScore: typeof ((
|
|
3341
|
+
collectionScore: typeof ((_z = params.toolResponseDebug) === null || _z === void 0 ? void 0 : _z.collectionScore) === 'number'
|
|
2987
3342
|
? params.toolResponseDebug.collectionScore
|
|
2988
3343
|
: undefined,
|
|
2989
|
-
query: ((
|
|
2990
|
-
pipeline: ((
|
|
2991
|
-
options: ((
|
|
2992
|
-
fallbacks: ((
|
|
3344
|
+
query: ((_0 = params.toolResponseDebug) === null || _0 === void 0 ? void 0 : _0.query) || undefined,
|
|
3345
|
+
pipeline: ((_1 = params.toolResponseDebug) === null || _1 === void 0 ? void 0 : _1.executedPipeline) || ((_2 = params.toolResponseDebug) === null || _2 === void 0 ? void 0 : _2.originalPipeline) || undefined,
|
|
3346
|
+
options: ((_3 = params.toolResponseDebug) === null || _3 === void 0 ? void 0 : _3.options) || undefined,
|
|
3347
|
+
fallbacks: ((_4 = params.toolResponseDebug) === null || _4 === void 0 ? void 0 : _4.fallbacks) || undefined,
|
|
2993
3348
|
notes: notes
|
|
2994
3349
|
};
|
|
2995
3350
|
if (params.trace && typeof params.trace === 'object') {
|
|
@@ -3022,6 +3377,9 @@ function buildAssistantToolErrorMessage(error, directive, request) {
|
|
|
3022
3377
|
if (normalized.includes('database access denied')) {
|
|
3023
3378
|
return "Database access is restricted for that request. ".concat(routeLine);
|
|
3024
3379
|
}
|
|
3380
|
+
if (normalized.includes('report builder bridge') && normalized.includes('not configured')) {
|
|
3381
|
+
return "That dataset is not configured for report builder access yet. ".concat(routeLine);
|
|
3382
|
+
}
|
|
3025
3383
|
if (normalized.includes('collection is required')) {
|
|
3026
3384
|
return 'I need a valid collection to read from. Please specify which screen or dataset you want.';
|
|
3027
3385
|
}
|
|
@@ -4716,30 +5074,30 @@ function ensureAssistantReadAccess(context, permissionView, collection) {
|
|
|
4716
5074
|
case 0:
|
|
4717
5075
|
idUser = context === null || context === void 0 ? void 0 : context.id_user;
|
|
4718
5076
|
if (!idUser) {
|
|
4719
|
-
throw new Error('AI assistant
|
|
5077
|
+
throw new Error('AI assistant report builder bridge: Unauthorized.');
|
|
4720
5078
|
}
|
|
4721
5079
|
return [4 /*yield*/, user_collection_1.Users.findById(idUser)];
|
|
4722
5080
|
case 1:
|
|
4723
5081
|
user = _b.sent();
|
|
4724
5082
|
if (!user) {
|
|
4725
|
-
throw new Error('AI assistant
|
|
5083
|
+
throw new Error('AI assistant report builder bridge: Unauthorized.');
|
|
4726
5084
|
}
|
|
4727
5085
|
isSuperAdmin = !!((_a = user === null || user === void 0 ? void 0 : user.roles) === null || _a === void 0 ? void 0 : _a.super_admin);
|
|
4728
5086
|
normalizedPermission = normalizeOptionalString(permissionView);
|
|
4729
5087
|
if (!isSuperAdmin) {
|
|
4730
5088
|
if (!normalizedPermission) {
|
|
4731
|
-
throw new Error('AI assistant
|
|
5089
|
+
throw new Error('AI assistant report builder bridge: Permission scope required.');
|
|
4732
5090
|
}
|
|
4733
5091
|
if (!userHasViewPermission(user, normalizedPermission)) {
|
|
4734
|
-
throw new Error('AI assistant
|
|
5092
|
+
throw new Error('AI assistant report builder bridge: Access denied.');
|
|
4735
5093
|
}
|
|
4736
5094
|
normalizedCollection = normalizeOptionalString(collection);
|
|
4737
5095
|
if (normalizedCollection && requiresInvoicePermission(normalizedCollection) && !userHasInvoiceAccess(user)) {
|
|
4738
|
-
throw new Error('AI assistant
|
|
5096
|
+
throw new Error('AI assistant report builder bridge: Access denied.');
|
|
4739
5097
|
}
|
|
4740
5098
|
}
|
|
4741
5099
|
else if (normalizedPermission && !userHasViewPermission(user, normalizedPermission)) {
|
|
4742
|
-
throw new Error('AI assistant
|
|
5100
|
+
throw new Error('AI assistant report builder bridge: Access denied.');
|
|
4743
5101
|
}
|
|
4744
5102
|
return [2 /*return*/, { user: user, isSuperAdmin: isSuperAdmin }];
|
|
4745
5103
|
}
|
|
@@ -4751,17 +5109,17 @@ function resolveAssistantDatabaseName(database, mongoConfig) {
|
|
|
4751
5109
|
var defaultDb = normalizeOptionalString(mongoConfig === null || mongoConfig === void 0 ? void 0 : mongoConfig.database) || ((_a = resolveio_server_app_1.ResolveIOServer.getServerConfig()) === null || _a === void 0 ? void 0 : _a.DATABASE) || '';
|
|
4752
5110
|
var dbName = normalizeOptionalString(database) || defaultDb;
|
|
4753
5111
|
if (!dbName) {
|
|
4754
|
-
throw new Error('AI assistant
|
|
5112
|
+
throw new Error('AI assistant report builder bridge: Database is required.');
|
|
4755
5113
|
}
|
|
4756
5114
|
var allowedFromConfig = Array.isArray(mongoConfig === null || mongoConfig === void 0 ? void 0 : mongoConfig.databases)
|
|
4757
5115
|
? mongoConfig === null || mongoConfig === void 0 ? void 0 : mongoConfig.databases.map(function (value) { return normalizeOptionalString(value); }).filter(Boolean)
|
|
4758
5116
|
: [];
|
|
4759
5117
|
if (allowedFromConfig.length && !allowedFromConfig.includes(dbName)) {
|
|
4760
|
-
throw new Error('AI assistant
|
|
5118
|
+
throw new Error('AI assistant report builder bridge: Database access denied.');
|
|
4761
5119
|
}
|
|
4762
5120
|
var allowedDatabases = ((_b = resolveio_server_app_1.ResolveIOServer.getMongoManager()) === null || _b === void 0 ? void 0 : _b.getWatchedDatabases()) || [];
|
|
4763
5121
|
if (allowedDatabases.length && !allowedDatabases.includes(dbName)) {
|
|
4764
|
-
throw new Error('AI assistant
|
|
5122
|
+
throw new Error('AI assistant report builder bridge: Database access denied.');
|
|
4765
5123
|
}
|
|
4766
5124
|
return dbName;
|
|
4767
5125
|
}
|
|
@@ -6606,7 +6964,7 @@ function replaceAggregateDateField(pipeline, fromField, toField) {
|
|
|
6606
6964
|
function normalizeMongoQuery(query) {
|
|
6607
6965
|
var normalized = query && typeof query === 'object' ? query : {};
|
|
6608
6966
|
if (containsForbiddenMongoOperators(normalized)) {
|
|
6609
|
-
throw new Error('AI assistant
|
|
6967
|
+
throw new Error('AI assistant report builder bridge: Query contains restricted operators.');
|
|
6610
6968
|
}
|
|
6611
6969
|
var rewritten = rewriteEmbeddedMatchObjects(normalized);
|
|
6612
6970
|
return applyAssistantNameRegexToQuery(rewritten);
|
|
@@ -6873,9 +7231,33 @@ function expandAssistantTermSynonyms(text) {
|
|
|
6873
7231
|
});
|
|
6874
7232
|
return { expanded: expanded, matches: matches };
|
|
6875
7233
|
}
|
|
7234
|
+
function listAssistantReportBuilderCollectionsFromManager() {
|
|
7235
|
+
var _a;
|
|
7236
|
+
var manager = (_a = resolveio_server_app_1.ResolveIOServer.getMongoManager) === null || _a === void 0 ? void 0 : _a.call(resolveio_server_app_1.ResolveIOServer);
|
|
7237
|
+
var collectionModels = manager && typeof manager.collections === 'function'
|
|
7238
|
+
? manager.collections()
|
|
7239
|
+
: [];
|
|
7240
|
+
if (!Array.isArray(collectionModels) || !collectionModels.length) {
|
|
7241
|
+
return [];
|
|
7242
|
+
}
|
|
7243
|
+
var seen = new Set();
|
|
7244
|
+
var names = [];
|
|
7245
|
+
collectionModels.forEach(function (model) {
|
|
7246
|
+
if (!(model === null || model === void 0 ? void 0 : model.useRB)) {
|
|
7247
|
+
return;
|
|
7248
|
+
}
|
|
7249
|
+
var name = normalizeOptionalString(model === null || model === void 0 ? void 0 : model.collectionName);
|
|
7250
|
+
if (!name || seen.has(name)) {
|
|
7251
|
+
return;
|
|
7252
|
+
}
|
|
7253
|
+
seen.add(name);
|
|
7254
|
+
names.push(name);
|
|
7255
|
+
});
|
|
7256
|
+
return names;
|
|
7257
|
+
}
|
|
6876
7258
|
function listAssistantCollections(db, dbName) {
|
|
6877
7259
|
return __awaiter(this, void 0, void 0, function () {
|
|
6878
|
-
var cacheKey, cached, now, collections, names, _a;
|
|
7260
|
+
var cacheKey, cached, now, reportBuilderCollections, collections, names, _a;
|
|
6879
7261
|
return __generator(this, function (_b) {
|
|
6880
7262
|
switch (_b.label) {
|
|
6881
7263
|
case 0:
|
|
@@ -6885,6 +7267,11 @@ function listAssistantCollections(db, dbName) {
|
|
|
6885
7267
|
if (cached && now - cached.updatedAt < AI_ASSISTANT_COLLECTION_CACHE_TTL_MS) {
|
|
6886
7268
|
return [2 /*return*/, cached.names];
|
|
6887
7269
|
}
|
|
7270
|
+
reportBuilderCollections = listAssistantReportBuilderCollectionsFromManager().sort(function (a, b) { return a.localeCompare(b); });
|
|
7271
|
+
if (reportBuilderCollections.length) {
|
|
7272
|
+
AI_ASSISTANT_COLLECTION_CACHE.set(cacheKey, { names: reportBuilderCollections, updatedAt: now });
|
|
7273
|
+
return [2 /*return*/, reportBuilderCollections];
|
|
7274
|
+
}
|
|
6888
7275
|
_b.label = 1;
|
|
6889
7276
|
case 1:
|
|
6890
7277
|
_b.trys.push([1, 3, , 4]);
|
|
@@ -7291,6 +7678,36 @@ function resolveAssistantCollectionName(db, dbName, requested) {
|
|
|
7291
7678
|
});
|
|
7292
7679
|
});
|
|
7293
7680
|
}
|
|
7681
|
+
function resolveAssistantReportBuilderBridgeCollection(collection) {
|
|
7682
|
+
var _a;
|
|
7683
|
+
var normalized = normalizeOptionalString(collection);
|
|
7684
|
+
if (!normalized) {
|
|
7685
|
+
throw new Error('AI assistant report builder bridge: Collection is required.');
|
|
7686
|
+
}
|
|
7687
|
+
var manager = (_a = resolveio_server_app_1.ResolveIOServer.getMongoManager) === null || _a === void 0 ? void 0 : _a.call(resolveio_server_app_1.ResolveIOServer);
|
|
7688
|
+
if (!manager || typeof manager.collection !== 'function') {
|
|
7689
|
+
throw new Error('AI assistant report builder bridge: Mongo manager unavailable.');
|
|
7690
|
+
}
|
|
7691
|
+
var directModel = manager.collection(normalized);
|
|
7692
|
+
if (directModel === null || directModel === void 0 ? void 0 : directModel.useRB) {
|
|
7693
|
+
return { collection: normalized };
|
|
7694
|
+
}
|
|
7695
|
+
var base = stripVersionSuffix(normalized.startsWith('report-') ? normalized.slice('report-'.length) : normalized);
|
|
7696
|
+
var reportCandidate = base ? "report-".concat(base) : '';
|
|
7697
|
+
if (reportCandidate && reportCandidate !== normalized) {
|
|
7698
|
+
var reportModel = manager.collection(reportCandidate);
|
|
7699
|
+
if (reportModel === null || reportModel === void 0 ? void 0 : reportModel.useRB) {
|
|
7700
|
+
return { collection: reportCandidate, fallbackFrom: normalized };
|
|
7701
|
+
}
|
|
7702
|
+
}
|
|
7703
|
+
if (base && base !== normalized) {
|
|
7704
|
+
var baseModel = manager.collection(base);
|
|
7705
|
+
if (baseModel === null || baseModel === void 0 ? void 0 : baseModel.useRB) {
|
|
7706
|
+
return { collection: base, fallbackFrom: normalized };
|
|
7707
|
+
}
|
|
7708
|
+
}
|
|
7709
|
+
throw new Error('AI assistant report builder bridge: Collection is not configured for report builder.');
|
|
7710
|
+
}
|
|
7294
7711
|
function findQueryDateField(query) {
|
|
7295
7712
|
var e_22, _a, e_23, _b;
|
|
7296
7713
|
if (!query || typeof query !== 'object') {
|
|
@@ -8355,7 +8772,7 @@ function buildAssistantCodexDirectivePrompt(message, attachmentText, historyText
|
|
|
8355
8772
|
var contextBlock = trimmedContext ? "\n\nContext:\n".concat(trimmedContext) : '';
|
|
8356
8773
|
var trimmedHistory = normalizeOptionalString(historyText);
|
|
8357
8774
|
var historyBlock = trimmedHistory ? "\n\nConversation so far:\n".concat(trimmedHistory) : '';
|
|
8358
|
-
var instruction = '\n\nInstruction:\nReturn ONLY a single
|
|
8775
|
+
var instruction = '\n\nInstruction:\nReturn ONLY a single REPORT_BUILDER_READ or REPORT_BUILDER_AGG directive line. Do not include any other text.';
|
|
8359
8776
|
return "System:\n".concat(AI_ASSISTANT_SYSTEM_PROMPT).concat(contextBlock).concat(historyBlock, "\n\nUser:\n").concat(message).concat(attachmentText || '').concat(instruction).trim();
|
|
8360
8777
|
}
|
|
8361
8778
|
function buildAssistantCodexPrompt(message, attachmentText, historyText, contextText) {
|
|
@@ -8365,6 +8782,88 @@ function buildAssistantCodexPrompt(message, attachmentText, historyText, context
|
|
|
8365
8782
|
var historyBlock = trimmedHistory ? "\n\nConversation so far:\n".concat(trimmedHistory) : '';
|
|
8366
8783
|
return "System:\n".concat(AI_ASSISTANT_SYSTEM_PROMPT).concat(contextBlock).concat(historyBlock, "\n\nUser:\n").concat(message).concat(attachmentText || '').trim();
|
|
8367
8784
|
}
|
|
8785
|
+
function resolveAssistantPlannerEnabled() {
|
|
8786
|
+
var _a;
|
|
8787
|
+
var config = ((_a = resolveio_server_app_1.ResolveIOServer.getServerConfig) === null || _a === void 0 ? void 0 : _a.call(resolveio_server_app_1.ResolveIOServer)) || {};
|
|
8788
|
+
var raw = normalizeOptionalBoolean(config['AI_ASSISTANT_CODEX_PLANNER_ENABLED']
|
|
8789
|
+
|| process.env.AI_ASSISTANT_CODEX_PLANNER_ENABLED);
|
|
8790
|
+
return raw === undefined ? true : raw === true;
|
|
8791
|
+
}
|
|
8792
|
+
function resolveAssistantPlannerKnownRoutes() {
|
|
8793
|
+
var e_26, _a;
|
|
8794
|
+
var _b;
|
|
8795
|
+
var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
|
|
8796
|
+
var unique = new Set();
|
|
8797
|
+
try {
|
|
8798
|
+
for (var routes_1 = __values(routes), routes_1_1 = routes_1.next(); !routes_1_1.done; routes_1_1 = routes_1.next()) {
|
|
8799
|
+
var route = routes_1_1.value;
|
|
8800
|
+
var normalized = normalizeRouteKey(route);
|
|
8801
|
+
if (normalized) {
|
|
8802
|
+
unique.add(normalized);
|
|
8803
|
+
}
|
|
8804
|
+
}
|
|
8805
|
+
}
|
|
8806
|
+
catch (e_26_1) { e_26 = { error: e_26_1 }; }
|
|
8807
|
+
finally {
|
|
8808
|
+
try {
|
|
8809
|
+
if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
|
|
8810
|
+
}
|
|
8811
|
+
finally { if (e_26) throw e_26.error; }
|
|
8812
|
+
}
|
|
8813
|
+
return Array.from(unique).slice(0, AI_ASSISTANT_PLANNER_MAX_ROUTES);
|
|
8814
|
+
}
|
|
8815
|
+
function buildAssistantPlannerUserSnapshot(user, inputClientId) {
|
|
8816
|
+
var _a, _b, _c, _d, _e;
|
|
8817
|
+
var groups = Array.isArray((_a = user === null || user === void 0 ? void 0 : user.roles) === null || _a === void 0 ? void 0 : _a.groups)
|
|
8818
|
+
? user.roles.groups.map(function (group) { return ({
|
|
8819
|
+
name: normalizeOptionalString(group === null || group === void 0 ? void 0 : group.name) || undefined,
|
|
8820
|
+
views: Array.isArray(group === null || group === void 0 ? void 0 : group.views) ? group.views.filter(Boolean) : []
|
|
8821
|
+
}); })
|
|
8822
|
+
: [];
|
|
8823
|
+
var miscs = Array.isArray((_b = user === null || user === void 0 ? void 0 : user.roles) === null || _b === void 0 ? void 0 : _b.miscs)
|
|
8824
|
+
? user.roles.miscs.filter(Boolean)
|
|
8825
|
+
: [];
|
|
8826
|
+
var other = {};
|
|
8827
|
+
var customerId = normalizeOptionalString((_c = user === null || user === void 0 ? void 0 : user.other) === null || _c === void 0 ? void 0 : _c.id_customer);
|
|
8828
|
+
if (customerId) {
|
|
8829
|
+
other.id_customer = customerId;
|
|
8830
|
+
}
|
|
8831
|
+
var clientId = normalizeOptionalString(inputClientId) || normalizeOptionalString((_d = user === null || user === void 0 ? void 0 : user.other) === null || _d === void 0 ? void 0 : _d.id_client);
|
|
8832
|
+
var snapshot = {
|
|
8833
|
+
_id: (user === null || user === void 0 ? void 0 : user._id) ? String(user._id) : undefined,
|
|
8834
|
+
username: normalizeOptionalString(user === null || user === void 0 ? void 0 : user.username) || undefined,
|
|
8835
|
+
fullname: normalizeOptionalString(user === null || user === void 0 ? void 0 : user.fullname) || undefined,
|
|
8836
|
+
roles: {
|
|
8837
|
+
super_admin: !!((_e = user === null || user === void 0 ? void 0 : user.roles) === null || _e === void 0 ? void 0 : _e.super_admin),
|
|
8838
|
+
groups: groups,
|
|
8839
|
+
miscs: miscs
|
|
8840
|
+
}
|
|
8841
|
+
};
|
|
8842
|
+
if (Object.keys(other).length) {
|
|
8843
|
+
snapshot.other = other;
|
|
8844
|
+
}
|
|
8845
|
+
if (clientId) {
|
|
8846
|
+
snapshot.id_client = clientId;
|
|
8847
|
+
}
|
|
8848
|
+
return snapshot;
|
|
8849
|
+
}
|
|
8850
|
+
function buildAssistantPlannerPrompt(params) {
|
|
8851
|
+
var todayIso = new Date().toISOString().slice(0, 10);
|
|
8852
|
+
var userMessage = "".concat(params.message || '').concat(params.attachmentText || '').trim();
|
|
8853
|
+
var currentRoute = normalizeOptionalString(params.contextRoute || '') || 'null';
|
|
8854
|
+
var userSnapshot = buildAssistantPlannerUserSnapshot(params.user, params.inputClientId);
|
|
8855
|
+
var templateData = {
|
|
8856
|
+
today_iso: todayIso,
|
|
8857
|
+
user_message: userMessage || '',
|
|
8858
|
+
current_route: currentRoute,
|
|
8859
|
+
known_routes_json_array: JSON.stringify(params.knownRoutes || []),
|
|
8860
|
+
user_json: JSON.stringify(userSnapshot || {}),
|
|
8861
|
+
collection_hints_json_array: JSON.stringify(params.collectionHints || []),
|
|
8862
|
+
field_hints_json_array: JSON.stringify(params.fieldHints || [])
|
|
8863
|
+
};
|
|
8864
|
+
var userPrompt = applyTemplate(AI_ASSISTANT_PLANNER_USER_PROMPT_TEMPLATE, templateData);
|
|
8865
|
+
return "System:\n".concat(AI_ASSISTANT_PLANNER_SYSTEM_PROMPT, "\n\nUser:\n").concat(userPrompt).trim();
|
|
8866
|
+
}
|
|
8368
8867
|
function buildAssistantContext(input, userContext) {
|
|
8369
8868
|
var _a, _b, _c, _d, _e, _f;
|
|
8370
8869
|
var lines = [];
|
|
@@ -8520,14 +9019,14 @@ function normalizeRouteMatchKey(value) {
|
|
|
8520
9019
|
return normalizeRouteKey(value).toLowerCase();
|
|
8521
9020
|
}
|
|
8522
9021
|
function buildClientRouteIndex() {
|
|
8523
|
-
var
|
|
9022
|
+
var e_27, _a;
|
|
8524
9023
|
var _b;
|
|
8525
9024
|
var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
|
|
8526
9025
|
var set = new Set();
|
|
8527
9026
|
var map = new Map();
|
|
8528
9027
|
try {
|
|
8529
|
-
for (var
|
|
8530
|
-
var route =
|
|
9028
|
+
for (var routes_2 = __values(routes), routes_2_1 = routes_2.next(); !routes_2_1.done; routes_2_1 = routes_2.next()) {
|
|
9029
|
+
var route = routes_2_1.value;
|
|
8531
9030
|
var normalized = normalizeRouteKey(route);
|
|
8532
9031
|
if (!normalized) {
|
|
8533
9032
|
continue;
|
|
@@ -8539,12 +9038,12 @@ function buildClientRouteIndex() {
|
|
|
8539
9038
|
}
|
|
8540
9039
|
}
|
|
8541
9040
|
}
|
|
8542
|
-
catch (
|
|
9041
|
+
catch (e_27_1) { e_27 = { error: e_27_1 }; }
|
|
8543
9042
|
finally {
|
|
8544
9043
|
try {
|
|
8545
|
-
if (
|
|
9044
|
+
if (routes_2_1 && !routes_2_1.done && (_a = routes_2.return)) _a.call(routes_2);
|
|
8546
9045
|
}
|
|
8547
|
-
finally { if (
|
|
9046
|
+
finally { if (e_27) throw e_27.error; }
|
|
8548
9047
|
}
|
|
8549
9048
|
return { set: set, map: map, size: routes.length };
|
|
8550
9049
|
}
|
|
@@ -8691,7 +9190,7 @@ function sanitizeAssistantResponse(value) {
|
|
|
8691
9190
|
return normalizeAssistantRoutes(normalizedCurrency);
|
|
8692
9191
|
}
|
|
8693
9192
|
function evaluateAssistantGuardrails(message) {
|
|
8694
|
-
var
|
|
9193
|
+
var e_28, _a;
|
|
8695
9194
|
var normalized = String(message || '').toLowerCase();
|
|
8696
9195
|
var patterns = [
|
|
8697
9196
|
{
|
|
@@ -8737,12 +9236,12 @@ function evaluateAssistantGuardrails(message) {
|
|
|
8737
9236
|
}
|
|
8738
9237
|
}
|
|
8739
9238
|
}
|
|
8740
|
-
catch (
|
|
9239
|
+
catch (e_28_1) { e_28 = { error: e_28_1 }; }
|
|
8741
9240
|
finally {
|
|
8742
9241
|
try {
|
|
8743
9242
|
if (patterns_1_1 && !patterns_1_1.done && (_a = patterns_1.return)) _a.call(patterns_1);
|
|
8744
9243
|
}
|
|
8745
|
-
finally { if (
|
|
9244
|
+
finally { if (e_28) throw e_28.error; }
|
|
8746
9245
|
}
|
|
8747
9246
|
return null;
|
|
8748
9247
|
}
|
|
@@ -8857,7 +9356,7 @@ function tokenizeArithmeticExpression(expression) {
|
|
|
8857
9356
|
return tokens;
|
|
8858
9357
|
}
|
|
8859
9358
|
function evaluateArithmeticExpression(expression) {
|
|
8860
|
-
var
|
|
9359
|
+
var e_29, _a, e_30, _b;
|
|
8861
9360
|
var tokens = tokenizeArithmeticExpression(expression);
|
|
8862
9361
|
if (!tokens || !tokens.length) {
|
|
8863
9362
|
return null;
|
|
@@ -8914,12 +9413,12 @@ function evaluateArithmeticExpression(expression) {
|
|
|
8914
9413
|
prevToken = token;
|
|
8915
9414
|
}
|
|
8916
9415
|
}
|
|
8917
|
-
catch (
|
|
9416
|
+
catch (e_29_1) { e_29 = { error: e_29_1 }; }
|
|
8918
9417
|
finally {
|
|
8919
9418
|
try {
|
|
8920
9419
|
if (tokens_1_1 && !tokens_1_1.done && (_a = tokens_1.return)) _a.call(tokens_1);
|
|
8921
9420
|
}
|
|
8922
|
-
finally { if (
|
|
9421
|
+
finally { if (e_29) throw e_29.error; }
|
|
8923
9422
|
}
|
|
8924
9423
|
while (ops.length) {
|
|
8925
9424
|
var op = ops.pop();
|
|
@@ -8959,12 +9458,12 @@ function evaluateArithmeticExpression(expression) {
|
|
|
8959
9458
|
stack.push(Number(token));
|
|
8960
9459
|
}
|
|
8961
9460
|
}
|
|
8962
|
-
catch (
|
|
9461
|
+
catch (e_30_1) { e_30 = { error: e_30_1 }; }
|
|
8963
9462
|
finally {
|
|
8964
9463
|
try {
|
|
8965
9464
|
if (output_1_1 && !output_1_1.done && (_b = output_1.return)) _b.call(output_1);
|
|
8966
9465
|
}
|
|
8967
|
-
finally { if (
|
|
9466
|
+
finally { if (e_30) throw e_30.error; }
|
|
8968
9467
|
}
|
|
8969
9468
|
if (stack.length !== 1 || Number.isNaN(stack[0])) {
|
|
8970
9469
|
return null;
|
|
@@ -9148,8 +9647,8 @@ function handleCodexUpload(id_conversation, file_name, content_base64, size, con
|
|
|
9148
9647
|
}
|
|
9149
9648
|
function readAttachmentContents(attachments) {
|
|
9150
9649
|
return __awaiter(this, void 0, void 0, function () {
|
|
9151
|
-
var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a,
|
|
9152
|
-
var
|
|
9650
|
+
var limits, totalBytes, totalChars, chunks, cleaned, attachments_1, attachments_1_1, attachment, localPath, safe, stat, ext, name_1, type, readable, content, _a, e_31_1;
|
|
9651
|
+
var e_31, _b;
|
|
9153
9652
|
return __generator(this, function (_c) {
|
|
9154
9653
|
switch (_c.label) {
|
|
9155
9654
|
case 0:
|
|
@@ -9228,14 +9727,14 @@ function readAttachmentContents(attachments) {
|
|
|
9228
9727
|
return [3 /*break*/, 2];
|
|
9229
9728
|
case 10: return [3 /*break*/, 13];
|
|
9230
9729
|
case 11:
|
|
9231
|
-
|
|
9232
|
-
|
|
9730
|
+
e_31_1 = _c.sent();
|
|
9731
|
+
e_31 = { error: e_31_1 };
|
|
9233
9732
|
return [3 /*break*/, 13];
|
|
9234
9733
|
case 12:
|
|
9235
9734
|
try {
|
|
9236
9735
|
if (attachments_1_1 && !attachments_1_1.done && (_b = attachments_1.return)) _b.call(attachments_1);
|
|
9237
9736
|
}
|
|
9238
|
-
finally { if (
|
|
9737
|
+
finally { if (e_31) throw e_31.error; }
|
|
9239
9738
|
return [7 /*endfinally*/];
|
|
9240
9739
|
case 13: return [2 /*return*/, {
|
|
9241
9740
|
promptText: chunks.length ? "\n\nAttachments:\n".concat(chunks.join('\n\n')) : '',
|
|
@@ -9423,7 +9922,7 @@ function estimateUsage(messages, responseText, model) {
|
|
|
9423
9922
|
};
|
|
9424
9923
|
}
|
|
9425
9924
|
function evaluateGuardrails(message) {
|
|
9426
|
-
var
|
|
9925
|
+
var e_32, _a;
|
|
9427
9926
|
var normalized = String(message || '').toLowerCase();
|
|
9428
9927
|
var patterns = [
|
|
9429
9928
|
{ pattern: /\b(source\s*code|full\s*code|entire\s*code|repo\s*dump|repository|git\s*clone)\b/i, reason: 'Code access is restricted.' },
|
|
@@ -9445,12 +9944,12 @@ function evaluateGuardrails(message) {
|
|
|
9445
9944
|
}
|
|
9446
9945
|
}
|
|
9447
9946
|
}
|
|
9448
|
-
catch (
|
|
9947
|
+
catch (e_32_1) { e_32 = { error: e_32_1 }; }
|
|
9449
9948
|
finally {
|
|
9450
9949
|
try {
|
|
9451
9950
|
if (patterns_2_1 && !patterns_2_1.done && (_a = patterns_2.return)) _a.call(patterns_2);
|
|
9452
9951
|
}
|
|
9453
|
-
finally { if (
|
|
9952
|
+
finally { if (e_32) throw e_32.error; }
|
|
9454
9953
|
}
|
|
9455
9954
|
return null;
|
|
9456
9955
|
}
|