@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.
@@ -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 Mongo access is allowed only via the MONGO_READ/MONGO_AGG directives (see below).',
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 Mongo read (limit 1-5) to learn the shape.',
384
- '- Prefer running a small Mongo read over asking multiple questions.',
385
- '- For any data request (counts, lists, breakdowns, recent/last items), you MUST run a MONGO_READ or MONGO_AGG before answering.',
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 MONGO_READ/MONGO_AGG to answer with real data when needed.',
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
- 'Mongo directives:',
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
- '- MONGO_READ: {"collection":"<name>","query":{...},"options":{"projection":{...},"sort":{...},"limit":20},"permissionView":"</route>"}',
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
- '- MONGO_AGG: {"collection":"<name>","pipeline":[...],"options":{"allowDiskUse":true,"limit":20},"permissionView":"</route>"}',
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 MONGO_READ (includeTotal). For breakdowns, rankings, or sums grouped by a field, use MONGO_AGG.',
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 MONGO_READ or MONGO_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.',
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 MONGO_READ/MONGO_AGG only to produce summaries/snapshots/health checks (not raw dumps) when permitted.',
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, _b, initialStart, directivePrompt, forcedStart, forcedDirective, _c, requestedCollection, cleanedResponseText, effectiveDirective, toolRequest, toolStart, toolResponse, _d, toolPayload, followupPrompt, followupStart, followupText, _e, error_2, error_3, finishedAt, finalNow, finishedAt, codexMs, draftingMs, finalMetadata, finalAssistantDoc;
1201
- var _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t;
1202
- return __generator(this, function (_u) {
1203
- switch (_u.label) {
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((_f = input === null || input === void 0 ? void 0 : input.context) === null || _f === void 0 ? void 0 : _f.route);
1252
- contextMode = normalizeOptionalString((_g = input === null || input === void 0 ? void 0 : input.context) === null || _g === void 0 ? void 0 : _g.mode);
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
- _u.label = 1;
1498
+ _x.label = 1;
1255
1499
  case 1:
1256
- _u.trys.push([1, 30, 31, 32]);
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
- _u.label = 2;
1521
+ _x.label = 2;
1278
1522
  case 2:
1279
- _u.trys.push([2, 4, , 5]);
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 = _u.sent();
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 = _u.sent();
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 = _u.sent();
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*/, 10];
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
- _u.label = 7;
1346
- case 7:
1347
- _u.trys.push([7, 9, , 10]);
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 8:
1351
- directiveText = _u.sent();
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((_h = directive.payload) === null || _h === void 0 ? void 0 : _h.collection) || '');
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((_j = directive.payload) === null || _j === void 0 ? void 0 : _j.collection) || undefined,
1363
- permissionView: normalizeOptionalString((_k = directive.payload) === null || _k === void 0 ? void 0 : _k.permissionView) || undefined
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*/, 10];
1367
- case 9:
1368
- _b = _u.sent();
1369
- return [3 /*break*/, 10];
1370
- case 10:
1371
- if (!!directive) return [3 /*break*/, 12];
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 11:
1376
- responseText = _u.sent();
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((_l = directive.payload) === null || _l === void 0 ? void 0 : _l.collection) || '');
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((_m = directive.payload) === null || _m === void 0 ? void 0 : _m.collection) || undefined,
1387
- permissionView: normalizeOptionalString((_o = directive.payload) === null || _o === void 0 ? void 0 : _o.permissionView) || undefined
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
- _u.label = 12;
1391
- case 12:
1392
- if (!(!directive && dataQuestion)) return [3 /*break*/, 16];
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
- _u.label = 13;
1396
- case 13:
1397
- _u.trys.push([13, 15, , 16]);
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 14:
1401
- directiveText = _u.sent();
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((_p = directive.payload) === null || _p === void 0 ? void 0 : _p.collection) || '');
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((_q = directive.payload) === null || _q === void 0 ? void 0 : _q.collection) || undefined,
1413
- permissionView: normalizeOptionalString((_r = directive.payload) === null || _r === void 0 ? void 0 : _r.permissionView) || undefined
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*/, 16];
1417
- case 15:
1418
- _c = _u.sent();
1419
- return [3 /*break*/, 16];
1420
- case 16:
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((_s = directive.payload) === null || _s === void 0 ? void 0 : _s.collection);
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((_t = directive.payload) === null || _t === void 0 ? void 0 : _t.permissionView) || contextRoute,
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*/, 28];
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
- _u.label = 17;
1454
- case 17:
1455
- _u.trys.push([17, 26, , 27]);
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*/, 19];
1458
- return [4 /*yield*/, executeAiAssistantMongoAggregate(toolRequest, context)];
1459
- case 18:
1460
- _d = _u.sent();
1461
- return [3 /*break*/, 21];
1462
- case 19: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
1463
- case 20:
1464
- _d = _u.sent();
1465
- _u.label = 21;
1466
- case 21:
1467
- toolResponse = _d;
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
- _u.label = 22;
1483
- case 22:
1484
- _u.trys.push([22, 24, , 25]);
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 23:
1488
- followupText = _u.sent();
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*/, 25];
1493
- case 24:
1494
- _e = _u.sent();
1773
+ return [3 /*break*/, 30];
1774
+ case 29:
1775
+ _f = _x.sent();
1495
1776
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
1496
- return [3 /*break*/, 25];
1497
- case 25: return [3 /*break*/, 27];
1498
- case 26:
1499
- error_2 = _u.sent();
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*/, 27];
1503
- case 27: return [3 /*break*/, 29];
1504
- case 28:
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
- _u.label = 29;
1508
- case 29: return [3 /*break*/, 32];
1509
- case 30:
1510
- error_3 = _u.sent();
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*/, 32];
1514
- case 31:
1794
+ return [3 /*break*/, 37];
1795
+ case 36:
1515
1796
  progressTracker.stop();
1516
1797
  return [7 /*endfinally*/];
1517
- case 32:
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*/, 34];
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 33:
1591
- _u.sent();
1592
- _u.label = 34;
1593
- case 34: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
1594
- case 35:
1595
- _u.sent();
1596
- if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 37];
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 36:
1599
- _u.sent();
1600
- _u.label = 37;
1601
- case 37: return [2 /*return*/, finalAssistantDoc];
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 mongo read: Collection is required.');
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 mongo read: Access denied.');
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 mongo read: Access denied.');
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 mongo aggregate: Collection is required.');
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 mongo aggregate: Access denied.');
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 mongo aggregate: Access denied.');
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 mongo aggregate: Pipeline contains restricted operators.');
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 MONGO_* directive. Output plain Markdown. Summarize first, then include a Markdown table.';
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 MONGO_* directive; ran a directive-only pass.');
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.reportFallback) === null || _u === void 0 ? void 0 : _u.used) {
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 ((_v = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.idLookup) === null || _v === void 0 ? void 0 : _v.used) {
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 ((_w = fallbackInfo === null || fallbackInfo === void 0 ? void 0 : fallbackInfo.idDisplayLookup) === null || _w === void 0 ? void 0 : _w.used) {
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 = ((_x = params.toolError) === null || _x === void 0 ? void 0 : _x.message) || String(params.toolError || '');
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 ((_y = params.toolResponseDebug) === null || _y === void 0 ? void 0 : _y.collectionScore) === 'number'
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: ((_z = params.toolResponseDebug) === null || _z === void 0 ? void 0 : _z.query) || undefined,
2990
- pipeline: ((_0 = params.toolResponseDebug) === null || _0 === void 0 ? void 0 : _0.executedPipeline) || ((_1 = params.toolResponseDebug) === null || _1 === void 0 ? void 0 : _1.originalPipeline) || undefined,
2991
- options: ((_2 = params.toolResponseDebug) === null || _2 === void 0 ? void 0 : _2.options) || undefined,
2992
- fallbacks: ((_3 = params.toolResponseDebug) === null || _3 === void 0 ? void 0 : _3.fallbacks) || undefined,
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 mongo read: Unauthorized.');
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 mongo read: Unauthorized.');
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 mongo read: Permission scope required.');
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 mongo read: Access denied.');
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 mongo read: Access denied.');
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 mongo read: Access denied.');
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 mongo read: Database is required.');
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 mongo read: Database access denied.');
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 mongo read: Database access denied.');
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 mongo read: Query contains restricted operators.');
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 MONGO_READ or MONGO_AGG directive line. Do not include any other text.';
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 e_26, _a;
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 routes_1 = __values(routes), routes_1_1 = routes_1.next(); !routes_1_1.done; routes_1_1 = routes_1.next()) {
8530
- var route = routes_1_1.value;
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 (e_26_1) { e_26 = { error: e_26_1 }; }
9041
+ catch (e_27_1) { e_27 = { error: e_27_1 }; }
8543
9042
  finally {
8544
9043
  try {
8545
- if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
9044
+ if (routes_2_1 && !routes_2_1.done && (_a = routes_2.return)) _a.call(routes_2);
8546
9045
  }
8547
- finally { if (e_26) throw e_26.error; }
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 e_27, _a;
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 (e_27_1) { e_27 = { error: e_27_1 }; }
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 (e_27) throw e_27.error; }
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 e_28, _a, e_29, _b;
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 (e_28_1) { e_28 = { error: e_28_1 }; }
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 (e_28) throw e_28.error; }
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 (e_29_1) { e_29 = { error: e_29_1 }; }
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 (e_29) throw e_29.error; }
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, e_30_1;
9152
- var e_30, _b;
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
- e_30_1 = _c.sent();
9232
- e_30 = { error: e_30_1 };
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 (e_30) throw e_30.error; }
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 e_31, _a;
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 (e_31_1) { e_31 = { error: e_31_1 }; }
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 (e_31) throw e_31.error; }
9952
+ finally { if (e_32) throw e_32.error; }
9454
9953
  }
9455
9954
  return null;
9456
9955
  }