@resolveio/server-lib 22.0.6 → 22.0.7

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 = [
@@ -450,6 +452,153 @@ var AI_ASSISTANT_SYSTEM_PROMPT = [
450
452
  '- 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
453
  '- Keep responses concise and use the configured reasoning effort level (default low).'
452
454
  ].join('\n');
455
+ var AI_ASSISTANT_PLANNER_SYSTEM_PROMPT = [
456
+ 'You are ResolveIO Assistant Planner. Your job is to produce a permissions-aware execution plan for the user\'s request.',
457
+ '',
458
+ 'HARD RULES (must follow):',
459
+ '1) PERMISSIONS FIRST: Determine access tier before planning anything.',
460
+ ' - If user.roles.super_admin === true: tier = "super_admin" (full access).',
461
+ ' - Else if user.other.id_customer exists (non-empty): tier = "customer_portal" (restrict to that customer\'s data + their views).',
462
+ ' - Else: tier = "client_user" (restrict to their views; client-scoped data).',
463
+ '',
464
+ '2) NEVER suggest pages/routes the user cannot access.',
465
+ ' - Only recommend routes that match their allowed views.',
466
+ ' - If route inventory is provided (KnownRoutes), choose from it. Do not invent new routes.',
467
+ ' - If no allowed route exists, propose the closest allowed route OR tell them they need access.',
468
+ '',
469
+ '3) DATA ACCESS MUST MATCH PERMISSIONS:',
470
+ ' - super_admin: no scope restriction required.',
471
+ ' - customer_portal: apply customer scope (id_customer or other.id_customer) to all data plans.',
472
+ ' - client_user: apply client scope (id_client) to all data plans.',
473
+ ' - Never propose querying blocked/sensitive collections if the user lacks permission.',
474
+ '',
475
+ '4) PERMISSION MATCHING:',
476
+ ' - Do NOT hardcode invoice access to "/report/invoice".',
477
+ ' - For invoice-related data or navigation, permission is satisfied if ANY user view contains "invoice" case-insensitive.',
478
+ ' (General rule: for an entity token X, permission is satisfied if any view contains X case-insensitive.)',
479
+ ' - If permission checks are ambiguous, choose the safest restriction and explain.',
480
+ '',
481
+ '5) CLASSIFY THE REQUEST:',
482
+ ' - type = "navigation" if user asks how/where to do something in the app.',
483
+ ' - type = "data" if user asks for totals, lists, breakdowns, counts, reports, "last N", "by month", etc.',
484
+ ' - type = "program_explain" if user asks how the system works (features/process).',
485
+ ' - type = "mixed" if both navigation + data are clearly requested.',
486
+ '',
487
+ '6) OUTPUT FORMAT:',
488
+ ' - Return ONLY a single JSON object (no markdown, no extra text).',
489
+ ' - The JSON must match the schema provided in the user prompt.',
490
+ ' - Be explicit and actionable. Prefer more guidance over less.',
491
+ ' - 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.',
492
+ '',
493
+ '7) USER-TONE PLANNING:',
494
+ ' - If user name is available, personalize greeting.',
495
+ ' - If group names are available, reference them in the plan (e.g., "Drivers group").',
496
+ ' - Always propose next steps from where they are (currentRoute if provided).',
497
+ ' - End plan with 1-2 engaging follow-up questions the assistant can ask the user.',
498
+ '',
499
+ '8) DO NOT run shell commands or read repo files in this planning step. Use only the provided context.'
500
+ ].join('\n');
501
+ var AI_ASSISTANT_PLANNER_USER_PROMPT_TEMPLATE = [
502
+ 'You MUST return JSON only, matching this schema:',
503
+ '',
504
+ '{',
505
+ ' "access": {',
506
+ ' "tier": "super_admin" | "customer_portal" | "client_user",',
507
+ ' "isSuperAdmin": boolean,',
508
+ ' "customerId": string | null,',
509
+ ' "clientId": string | null,',
510
+ ' "userDisplayName": string | null,',
511
+ ' "groupNames": string[],',
512
+ ' "allowedViews": string[],',
513
+ ' "permissionRules": {',
514
+ ' "entityPermissionMatch": "views_contains_token_case_insensitive",',
515
+ ' "invoicePermissionRegex": "invoice"',
516
+ ' }',
517
+ ' },',
518
+ ' "intent": {',
519
+ ' "type": "navigation" | "data" | "program_explain" | "mixed",',
520
+ ' "summary": string,',
521
+ ' "confidence": number',
522
+ ' },',
523
+ ' "navigationPlan": {',
524
+ ' "startingRoute": string | null,',
525
+ ' "recommendedRoutes": Array<{',
526
+ ' "route": string,',
527
+ ' "reason": string,',
528
+ ' "requiresViewToken": string',
529
+ ' }>,',
530
+ ' "stepByStep": string[],',
531
+ ' "deepLinks": Array<{',
532
+ ' "label": string,',
533
+ ' "route": string,',
534
+ ' "reason": string',
535
+ ' }>',
536
+ ' },',
537
+ ' "dataPlan": {',
538
+ ' "shouldFetchData": boolean,',
539
+ ' "permissionCheck": {',
540
+ ' "requiredViewToken": string | null,',
541
+ ' "allowed": boolean,',
542
+ ' "reason": string',
543
+ ' },',
544
+ ' "entity": string | null,',
545
+ ' "metric": string | null,',
546
+ ' "timeRange": {',
547
+ ' "type": "last_n_months" | "custom" | "all_time" | null,',
548
+ ' "n": number | null,',
549
+ ' "startDateISO": string | null,',
550
+ ' "endDateISO": string | null,',
551
+ ' "grain": "day" | "week" | "month" | "quarter" | null',
552
+ ' },',
553
+ ' "scoping": {',
554
+ ' "applyClientScope": boolean,',
555
+ ' "applyCustomerScope": boolean,',
556
+ ' "customerScopeField": "id_customer" | "other.id_customer" | null,',
557
+ ' "clientScopeField": "id_client" | null',
558
+ ' },',
559
+ ' "queryPlan": {',
560
+ ' "preferredCollections": string[],',
561
+ ' "fallbackCollections": string[],',
562
+ ' "dateFieldPreferences": string[],',
563
+ ' "amountFieldPreferences": string[],',
564
+ ' "statusStrategy": "none" | "paid_like" | "open_like" | "closed_like",',
565
+ ' "groupBy": string | null,',
566
+ ' "sort": string | null,',
567
+ ' "limit": number | null',
568
+ ' },',
569
+ ' "validationChecklist": string[]',
570
+ ' },',
571
+ ' "assistantResponsePlan": {',
572
+ ' "greeting": string,',
573
+ ' "whatINeedToSayFirst": string,',
574
+ ' "responseMustInclude": string[],',
575
+ ' "followUpQuestions": string[]',
576
+ ' }',
577
+ '}',
578
+ '',
579
+ 'Now produce a plan for the following request + context.',
580
+ '',
581
+ 'Today (ISO): {{today_iso}}',
582
+ 'User request: {{user_message}}',
583
+ '',
584
+ 'Current route (may be null): {{current_route}}',
585
+ 'Known routes (may be empty): {{known_routes_json_array}}',
586
+ '',
587
+ 'User object (sanitized): {{user_json}}',
588
+ 'Notes:',
589
+ '- user.roles.super_admin may exist',
590
+ '- user.roles.groups may include { name, views: [] }',
591
+ '- user.roles.miscs may include views strings',
592
+ '- user.other.id_customer may exist for customer portal users',
593
+ '',
594
+ 'Collection hints (may be empty): {{collection_hints_json_array}}',
595
+ 'Field hints (may be empty): {{field_hints_json_array}}',
596
+ '',
597
+ 'Important:',
598
+ '- If invoice-related, permission is satisfied if ANY allowed view contains "invoice" case-insensitive.',
599
+ '- Do not output raw Mongo pipelines. Output a QueryPlan + validation checklist only.',
600
+ '- Navigation steps must only reference routes that match allowed views (or known routes if provided).'
601
+ ].join('\n');
453
602
  var AI_FORM_PATCH_SYSTEM_PROMPT = [
454
603
  'You are the ResolveIO form patch assistant.',
455
604
  '- Your job is to map the user request to the provided form fields.',
@@ -1197,10 +1346,10 @@ function executeAiAssistantCodexRun(payload, context) {
1197
1346
  insertResult = _d.sent();
1198
1347
  assistantMessageId = (insertResult === null || insertResult === void 0 ? void 0 : insertResult._id) || (insertResult === null || insertResult === void 0 ? void 0 : insertResult.insertedId);
1199
1348
  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) {
1349
+ 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;
1350
+ var _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w;
1351
+ return __generator(this, function (_x) {
1352
+ switch (_x.label) {
1204
1353
  case 0:
1205
1354
  runStart = Date.now();
1206
1355
  if (aiWorkerDebug) {
@@ -1241,19 +1390,23 @@ function executeAiAssistantCodexRun(payload, context) {
1241
1390
  collectionSelection = null;
1242
1391
  collectionOverride = null;
1243
1392
  collectionNames = [];
1393
+ plannerEnabled = resolveAssistantPlannerEnabled();
1394
+ plannerOutput = null;
1395
+ plannerRaw = '';
1244
1396
  timingBreakdown = {
1397
+ plannerMs: 0,
1245
1398
  directiveMs: 0,
1246
1399
  initialResponseMs: 0,
1247
1400
  forcedDirectiveMs: 0,
1248
1401
  toolMs: 0,
1249
1402
  followupMs: 0
1250
1403
  };
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);
1404
+ contextRoute = normalizeOptionalString((_g = input === null || input === void 0 ? void 0 : input.context) === null || _g === void 0 ? void 0 : _g.route);
1405
+ contextMode = normalizeOptionalString((_h = input === null || input === void 0 ? void 0 : input.context) === null || _h === void 0 ? void 0 : _h.mode);
1253
1406
  recordStep('Queued', { requestId: requestId || undefined });
1254
- _u.label = 1;
1407
+ _x.label = 1;
1255
1408
  case 1:
1256
- _u.trys.push([1, 30, 31, 32]);
1409
+ _x.trys.push([1, 35, 36, 37]);
1257
1410
  hintSeed = [message, contextRoute].filter(Boolean).join(' ');
1258
1411
  termExpansion = expandAssistantTermSynonyms(hintSeed);
1259
1412
  hintText = termExpansion.expanded || hintSeed;
@@ -1274,19 +1427,19 @@ function executeAiAssistantCodexRun(payload, context) {
1274
1427
  recordStep('Planning: term expansion', {
1275
1428
  termMatches: termExpansion.matches.length ? termExpansion.matches : undefined
1276
1429
  });
1277
- _u.label = 2;
1430
+ _x.label = 2;
1278
1431
  case 2:
1279
- _u.trys.push([2, 4, , 5]);
1432
+ _x.trys.push([2, 4, , 5]);
1280
1433
  dbName = resolveAssistantDatabaseName(undefined, input.mongo);
1281
1434
  db = resolveio_server_app_1.ResolveIOServer.getMongoConnection().db(dbName);
1282
1435
  return [4 /*yield*/, listAssistantCollections(db, dbName)];
1283
1436
  case 3:
1284
- collectionNames = _u.sent();
1437
+ collectionNames = _x.sent();
1285
1438
  collectionHints = resolveCollectionHintsFromTokens(expandedTokens, collectionNames, 5);
1286
1439
  collectionRanking = buildCollectionRankingDebugFromTokens(expandedTokens, collectionNames, 8);
1287
1440
  return [3 /*break*/, 5];
1288
1441
  case 4:
1289
- _a = _u.sent();
1442
+ _a = _x.sent();
1290
1443
  collectionHints = [];
1291
1444
  collectionRanking = collectionRanking || ((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens)
1292
1445
  ? buildCollectionRankingDebugFromTokens(collectionTokenization.expandedTokens || [], [], 0)
@@ -1321,7 +1474,7 @@ function executeAiAssistantCodexRun(payload, context) {
1321
1474
  prompt_1 = buildAssistantCodexPrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1322
1475
  return [4 /*yield*/, resolveAssistantWorkspaceRoot()];
1323
1476
  case 6:
1324
- workspaceRoot = _u.sent();
1477
+ workspaceRoot = _x.sent();
1325
1478
  codexConfig = resolveCodexSettings();
1326
1479
  runOptions = {
1327
1480
  timeoutMs: resolveCodexTimeoutMs(),
@@ -1336,95 +1489,132 @@ function executeAiAssistantCodexRun(payload, context) {
1336
1489
  approvalPolicy: 'never'
1337
1490
  }
1338
1491
  };
1492
+ if (!plannerEnabled) return [3 /*break*/, 11];
1493
+ recordStep('Planning: planner prompt');
1494
+ plannerPrompt = buildAssistantPlannerPrompt({
1495
+ message: message,
1496
+ attachmentText: attachmentData.promptText,
1497
+ contextRoute: contextRoute,
1498
+ knownRoutes: resolveAssistantPlannerKnownRoutes(),
1499
+ user: user,
1500
+ collectionHints: collectionHints,
1501
+ fieldHints: fieldHints,
1502
+ inputClientId: input.id_client
1503
+ });
1504
+ _x.label = 7;
1505
+ case 7:
1506
+ _x.trys.push([7, 9, , 10]);
1507
+ plannerStart = Date.now();
1508
+ return [4 /*yield*/, runCodexInWorkerThread(plannerPrompt, runOptions, codexConfig, streamProgress)];
1509
+ case 8:
1510
+ plannerRaw = _x.sent();
1511
+ timingBreakdown.plannerMs = Date.now() - plannerStart;
1512
+ plannerOutput = parseJsonObject(plannerRaw);
1513
+ recordStep('Planning: planner result', { parsed: !!plannerOutput });
1514
+ return [3 /*break*/, 10];
1515
+ case 9:
1516
+ _b = _x.sent();
1517
+ recordStep('Planning: planner result', { parsed: false });
1518
+ return [3 /*break*/, 10];
1519
+ case 10:
1520
+ if (plannerOutput) {
1521
+ intentType = normalizeOptionalString((_j = plannerOutput === null || plannerOutput === void 0 ? void 0 : plannerOutput.intent) === null || _j === void 0 ? void 0 : _j.type).toLowerCase();
1522
+ shouldFetch = ((_k = plannerOutput === null || plannerOutput === void 0 ? void 0 : plannerOutput.dataPlan) === null || _k === void 0 ? void 0 : _k.shouldFetchData) === true;
1523
+ if (shouldFetch || intentType === 'data' || intentType === 'mixed') {
1524
+ dataQuestion = true;
1525
+ }
1526
+ }
1527
+ _x.label = 11;
1528
+ case 11:
1339
1529
  responseText = '';
1340
1530
  directiveText = '';
1341
1531
  directive = null;
1342
- if (!dataQuestion) return [3 /*break*/, 10];
1532
+ if (!dataQuestion) return [3 /*break*/, 15];
1343
1533
  recordStep('Directive: determine tool', { type: 'data-question' });
1344
1534
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1345
- _u.label = 7;
1346
- case 7:
1347
- _u.trys.push([7, 9, , 10]);
1535
+ _x.label = 12;
1536
+ case 12:
1537
+ _x.trys.push([12, 14, , 15]);
1348
1538
  directiveStart = Date.now();
1349
1539
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1350
- case 8:
1351
- directiveText = _u.sent();
1540
+ case 13:
1541
+ directiveText = _x.sent();
1352
1542
  timingBreakdown.directiveMs = Date.now() - directiveStart;
1353
1543
  forcedDirective = extractAssistantMongoDirective(directiveText);
1354
1544
  if (forcedDirective) {
1355
1545
  directive = forcedDirective;
1356
1546
  directiveSource = 'model';
1357
1547
  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) || '');
1548
+ collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((_l = directive.payload) === null || _l === void 0 ? void 0 : _l.collection) || '');
1359
1549
  recordStep('Directive resolved', {
1360
1550
  source: directiveSource,
1361
1551
  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
1552
+ collection: normalizeOptionalString((_m = directive.payload) === null || _m === void 0 ? void 0 : _m.collection) || undefined,
1553
+ permissionView: normalizeOptionalString((_o = directive.payload) === null || _o === void 0 ? void 0 : _o.permissionView) || undefined
1364
1554
  });
1365
1555
  }
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];
1556
+ return [3 /*break*/, 15];
1557
+ case 14:
1558
+ _c = _x.sent();
1559
+ return [3 /*break*/, 15];
1560
+ case 15:
1561
+ if (!!directive) return [3 /*break*/, 17];
1372
1562
  recordStep('Response: draft initial answer', { mode: 'full' });
1373
1563
  initialStart = Date.now();
1374
1564
  return [4 /*yield*/, runCodexInWorkerThread(prompt_1, runOptions, codexConfig, streamProgress)];
1375
- case 11:
1376
- responseText = _u.sent();
1565
+ case 16:
1566
+ responseText = _x.sent();
1377
1567
  timingBreakdown.initialResponseMs = Date.now() - initialStart;
1378
1568
  directive = extractAssistantMongoDirective(responseText);
1379
1569
  if (directive) {
1380
1570
  directiveSource = 'model';
1381
1571
  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) || '');
1572
+ collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((_p = directive.payload) === null || _p === void 0 ? void 0 : _p.collection) || '');
1383
1573
  recordStep('Directive resolved', {
1384
1574
  source: directiveSource,
1385
1575
  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
1576
+ collection: normalizeOptionalString((_q = directive.payload) === null || _q === void 0 ? void 0 : _q.collection) || undefined,
1577
+ permissionView: normalizeOptionalString((_r = directive.payload) === null || _r === void 0 ? void 0 : _r.permissionView) || undefined
1388
1578
  });
1389
1579
  }
1390
- _u.label = 12;
1391
- case 12:
1392
- if (!(!directive && dataQuestion)) return [3 /*break*/, 16];
1580
+ _x.label = 17;
1581
+ case 17:
1582
+ if (!(!directive && dataQuestion)) return [3 /*break*/, 21];
1393
1583
  recordStep('Directive: forced retry', { mode: 'directive-only' });
1394
1584
  directivePrompt = buildAssistantCodexDirectivePrompt(message, attachmentData.promptText, historyLines.join('\n'), assistantContext);
1395
- _u.label = 13;
1396
- case 13:
1397
- _u.trys.push([13, 15, , 16]);
1585
+ _x.label = 18;
1586
+ case 18:
1587
+ _x.trys.push([18, 20, , 21]);
1398
1588
  forcedStart = Date.now();
1399
1589
  return [4 /*yield*/, runCodexInWorkerThread(directivePrompt, runOptions, codexConfig, streamProgress)];
1400
- case 14:
1401
- directiveText = _u.sent();
1590
+ case 19:
1591
+ directiveText = _x.sent();
1402
1592
  timingBreakdown.forcedDirectiveMs = Date.now() - forcedStart;
1403
1593
  forcedDirective = extractAssistantMongoDirective(directiveText);
1404
1594
  if (forcedDirective) {
1405
1595
  directive = forcedDirective;
1406
1596
  directiveSource = 'forced';
1407
1597
  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) || '');
1598
+ collectionSelection = buildCollectionSelectionDetail((collectionTokenization === null || collectionTokenization === void 0 ? void 0 : collectionTokenization.expandedTokens) || [], normalizeOptionalString((_s = directive.payload) === null || _s === void 0 ? void 0 : _s.collection) || '');
1409
1599
  recordStep('Directive resolved', {
1410
1600
  source: directiveSource,
1411
1601
  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
1602
+ collection: normalizeOptionalString((_t = directive.payload) === null || _t === void 0 ? void 0 : _t.collection) || undefined,
1603
+ permissionView: normalizeOptionalString((_u = directive.payload) === null || _u === void 0 ? void 0 : _u.permissionView) || undefined
1414
1604
  });
1415
1605
  }
1416
- return [3 /*break*/, 16];
1417
- case 15:
1418
- _c = _u.sent();
1419
- return [3 /*break*/, 16];
1420
- case 16:
1606
+ return [3 /*break*/, 21];
1607
+ case 20:
1608
+ _d = _x.sent();
1609
+ return [3 /*break*/, 21];
1610
+ case 21:
1421
1611
  if (directive) {
1422
- requestedCollection = normalizeOptionalString((_s = directive.payload) === null || _s === void 0 ? void 0 : _s.collection);
1612
+ requestedCollection = normalizeOptionalString((_v = directive.payload) === null || _v === void 0 ? void 0 : _v.collection);
1423
1613
  collectionOverride = resolveCollectionOverrideWithContext({
1424
1614
  message: message,
1425
1615
  collectionRanking: collectionRanking,
1426
1616
  requestedCollection: requestedCollection,
1427
- permissionView: normalizeOptionalString((_t = directive.payload) === null || _t === void 0 ? void 0 : _t.permissionView) || contextRoute,
1617
+ permissionView: normalizeOptionalString((_w = directive.payload) === null || _w === void 0 ? void 0 : _w.permissionView) || contextRoute,
1428
1618
  collectionNames: collectionNames
1429
1619
  });
1430
1620
  if (collectionOverride) {
@@ -1440,7 +1630,7 @@ function executeAiAssistantCodexRun(payload, context) {
1440
1630
  if (cleanedResponseText) {
1441
1631
  assistantContent = sanitizeAssistantResponse(cleanedResponseText);
1442
1632
  }
1443
- if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 28];
1633
+ if (!((directive === null || directive === void 0 ? void 0 : directive.payload) && AI_ASSISTANT_TOOL_MAX_STEPS > 0)) return [3 /*break*/, 33];
1444
1634
  effectiveDirective = collectionOverride
1445
1635
  ? __assign(__assign({}, directive), { payload: __assign(__assign({}, (directive.payload || {})), { collection: collectionOverride.to }) }) : directive;
1446
1636
  toolRequest = buildAssistantToolRequest(effectiveDirective, input);
@@ -1450,21 +1640,21 @@ function executeAiAssistantCodexRun(payload, context) {
1450
1640
  collection: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.collection) || undefined,
1451
1641
  permissionView: normalizeOptionalString(toolRequest === null || toolRequest === void 0 ? void 0 : toolRequest.permissionView) || undefined
1452
1642
  });
1453
- _u.label = 17;
1454
- case 17:
1455
- _u.trys.push([17, 26, , 27]);
1643
+ _x.label = 22;
1644
+ case 22:
1645
+ _x.trys.push([22, 31, , 32]);
1456
1646
  toolStart = Date.now();
1457
- if (!(effectiveDirective.type === 'aggregate')) return [3 /*break*/, 19];
1647
+ if (!(effectiveDirective.type === 'aggregate')) return [3 /*break*/, 24];
1458
1648
  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;
1649
+ case 23:
1650
+ _e = _x.sent();
1651
+ return [3 /*break*/, 26];
1652
+ case 24: return [4 /*yield*/, executeAiAssistantMongoRead(toolRequest, context)];
1653
+ case 25:
1654
+ _e = _x.sent();
1655
+ _x.label = 26;
1656
+ case 26:
1657
+ toolResponse = _e;
1468
1658
  timingBreakdown.toolMs = Date.now() - toolStart;
1469
1659
  toolResponseDebug = (toolResponse === null || toolResponse === void 0 ? void 0 : toolResponse.debug) && typeof toolResponse.debug === 'object'
1470
1660
  ? toolResponse.debug
@@ -1479,42 +1669,42 @@ function executeAiAssistantCodexRun(payload, context) {
1479
1669
  progressTracker.push('Drafting response');
1480
1670
  recordStep('Drafting response');
1481
1671
  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]);
1672
+ _x.label = 27;
1673
+ case 27:
1674
+ _x.trys.push([27, 29, , 30]);
1485
1675
  followupStart = Date.now();
1486
1676
  return [4 /*yield*/, runCodexInWorkerThread(followupPrompt, runOptions, codexConfig, streamProgress)];
1487
- case 23:
1488
- followupText = _u.sent();
1677
+ case 28:
1678
+ followupText = _x.sent();
1489
1679
  timingBreakdown.followupMs = Date.now() - followupStart;
1490
1680
  assistantContent = sanitizeAssistantResponse(followupText);
1491
1681
  assistantContent = applyAssistantDisplayTableToResponse(assistantContent, toolPayload.result.output.display);
1492
- return [3 /*break*/, 25];
1493
- case 24:
1494
- _e = _u.sent();
1682
+ return [3 /*break*/, 30];
1683
+ case 29:
1684
+ _f = _x.sent();
1495
1685
  assistantContent = buildAssistantToolFallbackResponse(toolPayload.result);
1496
- return [3 /*break*/, 25];
1497
- case 25: return [3 /*break*/, 27];
1498
- case 26:
1499
- error_2 = _u.sent();
1686
+ return [3 /*break*/, 30];
1687
+ case 30: return [3 /*break*/, 32];
1688
+ case 31:
1689
+ error_2 = _x.sent();
1500
1690
  assistantContent = buildAssistantToolErrorMessage(error_2, directive, toolRequest);
1501
1691
  toolError = error_2;
1502
- return [3 /*break*/, 27];
1503
- case 27: return [3 /*break*/, 29];
1504
- case 28:
1692
+ return [3 /*break*/, 32];
1693
+ case 32: return [3 /*break*/, 34];
1694
+ case 33:
1505
1695
  progressTracker.push('Drafting response');
1506
1696
  recordStep('Drafting response');
1507
- _u.label = 29;
1508
- case 29: return [3 /*break*/, 32];
1509
- case 30:
1510
- error_3 = _u.sent();
1697
+ _x.label = 34;
1698
+ case 34: return [3 /*break*/, 37];
1699
+ case 35:
1700
+ error_3 = _x.sent();
1511
1701
  assistantContent = buildAssistantCodexErrorMessage(error_3);
1512
1702
  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:
1703
+ return [3 /*break*/, 37];
1704
+ case 36:
1515
1705
  progressTracker.stop();
1516
1706
  return [7 /*endfinally*/];
1517
- case 32:
1707
+ case 37:
1518
1708
  if (!assistantContent) {
1519
1709
  assistantContent = buildAssistantCodexErrorMessage(null);
1520
1710
  }
@@ -1537,6 +1727,7 @@ function executeAiAssistantCodexRun(payload, context) {
1537
1727
  if (isSuperAdmin) {
1538
1728
  finishedAt = Date.now();
1539
1729
  codexMs = timingBreakdown.directiveMs
1730
+ + timingBreakdown.plannerMs
1540
1731
  + timingBreakdown.initialResponseMs
1541
1732
  + timingBreakdown.forcedDirectiveMs
1542
1733
  + timingBreakdown.followupMs;
@@ -1560,7 +1751,15 @@ function executeAiAssistantCodexRun(payload, context) {
1560
1751
  collectionTokenization: collectionTokenization || undefined,
1561
1752
  collectionRanking: collectionRanking || undefined,
1562
1753
  collectionSelection: collectionSelection || undefined,
1563
- collectionOverride: collectionOverride || undefined
1754
+ collectionOverride: collectionOverride || undefined,
1755
+ planner: plannerEnabled ? {
1756
+ enabled: true,
1757
+ parsed: !!plannerOutput,
1758
+ output: plannerOutput || undefined,
1759
+ raw: !plannerOutput && plannerRaw
1760
+ ? plannerRaw.slice(0, AI_ASSISTANT_PLANNER_DEBUG_MAX_CHARS)
1761
+ : undefined
1762
+ } : undefined
1564
1763
  },
1565
1764
  timings: {
1566
1765
  startedAt: new Date(runStart).toISOString(),
@@ -1569,6 +1768,7 @@ function executeAiAssistantCodexRun(payload, context) {
1569
1768
  codexMs: codexMs,
1570
1769
  draftingMs: draftingMs,
1571
1770
  toolMs: timingBreakdown.toolMs,
1771
+ plannerMs: timingBreakdown.plannerMs,
1572
1772
  directiveMs: timingBreakdown.directiveMs,
1573
1773
  initialResponseMs: timingBreakdown.initialResponseMs,
1574
1774
  forcedDirectiveMs: timingBreakdown.forcedDirectiveMs,
@@ -1579,7 +1779,7 @@ function executeAiAssistantCodexRun(payload, context) {
1579
1779
  }
1580
1780
  finalMetadata = __assign(__assign(__assign({ model: resolveCodexModel() }, (requestId ? { request_id: requestId } : {})), (toolResult ? { tool_result: toolResult } : {})), (assistantDebug ? { debug: assistantDebug } : {}));
1581
1781
  finalAssistantDoc = __assign(__assign({}, assistantDoc), { _id: assistantMessageId, content: assistantContent, metadata: finalMetadata, updatedAt: finalNow });
1582
- if (!assistantMessageId) return [3 /*break*/, 34];
1782
+ if (!assistantMessageId) return [3 /*break*/, 39];
1583
1783
  return [4 /*yield*/, ai_terminal_message_collection_1.AiTerminalMessages.updateOne({ _id: assistantMessageId }, {
1584
1784
  $set: {
1585
1785
  content: assistantContent,
@@ -1587,18 +1787,18 @@ function executeAiAssistantCodexRun(payload, context) {
1587
1787
  updatedAt: finalNow
1588
1788
  }
1589
1789
  })];
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];
1790
+ case 38:
1791
+ _x.sent();
1792
+ _x.label = 39;
1793
+ case 39: return [4 /*yield*/, touchConversation(conversation._id, finalNow, assistantMessageId ? String(assistantMessageId) : undefined)];
1794
+ case 40:
1795
+ _x.sent();
1796
+ if (!(input.delete_files_after_run !== false)) return [3 /*break*/, 42];
1597
1797
  return [4 /*yield*/, cleanupAttachments(attachmentData.attachments)];
1598
- case 36:
1599
- _u.sent();
1600
- _u.label = 37;
1601
- case 37: return [2 /*return*/, finalAssistantDoc];
1798
+ case 41:
1799
+ _x.sent();
1800
+ _x.label = 42;
1801
+ case 42: return [2 /*return*/, finalAssistantDoc];
1602
1802
  }
1603
1803
  });
1604
1804
  }); });
@@ -8365,6 +8565,88 @@ function buildAssistantCodexPrompt(message, attachmentText, historyText, context
8365
8565
  var historyBlock = trimmedHistory ? "\n\nConversation so far:\n".concat(trimmedHistory) : '';
8366
8566
  return "System:\n".concat(AI_ASSISTANT_SYSTEM_PROMPT).concat(contextBlock).concat(historyBlock, "\n\nUser:\n").concat(message).concat(attachmentText || '').trim();
8367
8567
  }
8568
+ function resolveAssistantPlannerEnabled() {
8569
+ var _a;
8570
+ var config = ((_a = resolveio_server_app_1.ResolveIOServer.getServerConfig) === null || _a === void 0 ? void 0 : _a.call(resolveio_server_app_1.ResolveIOServer)) || {};
8571
+ var raw = normalizeOptionalBoolean(config['AI_ASSISTANT_CODEX_PLANNER_ENABLED']
8572
+ || process.env.AI_ASSISTANT_CODEX_PLANNER_ENABLED);
8573
+ return raw === undefined ? true : raw === true;
8574
+ }
8575
+ function resolveAssistantPlannerKnownRoutes() {
8576
+ var e_26, _a;
8577
+ var _b;
8578
+ var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
8579
+ var unique = new Set();
8580
+ try {
8581
+ for (var routes_1 = __values(routes), routes_1_1 = routes_1.next(); !routes_1_1.done; routes_1_1 = routes_1.next()) {
8582
+ var route = routes_1_1.value;
8583
+ var normalized = normalizeRouteKey(route);
8584
+ if (normalized) {
8585
+ unique.add(normalized);
8586
+ }
8587
+ }
8588
+ }
8589
+ catch (e_26_1) { e_26 = { error: e_26_1 }; }
8590
+ finally {
8591
+ try {
8592
+ if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
8593
+ }
8594
+ finally { if (e_26) throw e_26.error; }
8595
+ }
8596
+ return Array.from(unique).slice(0, AI_ASSISTANT_PLANNER_MAX_ROUTES);
8597
+ }
8598
+ function buildAssistantPlannerUserSnapshot(user, inputClientId) {
8599
+ var _a, _b, _c, _d, _e;
8600
+ var groups = Array.isArray((_a = user === null || user === void 0 ? void 0 : user.roles) === null || _a === void 0 ? void 0 : _a.groups)
8601
+ ? user.roles.groups.map(function (group) { return ({
8602
+ name: normalizeOptionalString(group === null || group === void 0 ? void 0 : group.name) || undefined,
8603
+ views: Array.isArray(group === null || group === void 0 ? void 0 : group.views) ? group.views.filter(Boolean) : []
8604
+ }); })
8605
+ : [];
8606
+ var miscs = Array.isArray((_b = user === null || user === void 0 ? void 0 : user.roles) === null || _b === void 0 ? void 0 : _b.miscs)
8607
+ ? user.roles.miscs.filter(Boolean)
8608
+ : [];
8609
+ var other = {};
8610
+ var customerId = normalizeOptionalString((_c = user === null || user === void 0 ? void 0 : user.other) === null || _c === void 0 ? void 0 : _c.id_customer);
8611
+ if (customerId) {
8612
+ other.id_customer = customerId;
8613
+ }
8614
+ var clientId = normalizeOptionalString(inputClientId) || normalizeOptionalString((_d = user === null || user === void 0 ? void 0 : user.other) === null || _d === void 0 ? void 0 : _d.id_client);
8615
+ var snapshot = {
8616
+ _id: (user === null || user === void 0 ? void 0 : user._id) ? String(user._id) : undefined,
8617
+ username: normalizeOptionalString(user === null || user === void 0 ? void 0 : user.username) || undefined,
8618
+ fullname: normalizeOptionalString(user === null || user === void 0 ? void 0 : user.fullname) || undefined,
8619
+ roles: {
8620
+ super_admin: !!((_e = user === null || user === void 0 ? void 0 : user.roles) === null || _e === void 0 ? void 0 : _e.super_admin),
8621
+ groups: groups,
8622
+ miscs: miscs
8623
+ }
8624
+ };
8625
+ if (Object.keys(other).length) {
8626
+ snapshot.other = other;
8627
+ }
8628
+ if (clientId) {
8629
+ snapshot.id_client = clientId;
8630
+ }
8631
+ return snapshot;
8632
+ }
8633
+ function buildAssistantPlannerPrompt(params) {
8634
+ var todayIso = new Date().toISOString().slice(0, 10);
8635
+ var userMessage = "".concat(params.message || '').concat(params.attachmentText || '').trim();
8636
+ var currentRoute = normalizeOptionalString(params.contextRoute || '') || 'null';
8637
+ var userSnapshot = buildAssistantPlannerUserSnapshot(params.user, params.inputClientId);
8638
+ var templateData = {
8639
+ today_iso: todayIso,
8640
+ user_message: userMessage || '',
8641
+ current_route: currentRoute,
8642
+ known_routes_json_array: JSON.stringify(params.knownRoutes || []),
8643
+ user_json: JSON.stringify(userSnapshot || {}),
8644
+ collection_hints_json_array: JSON.stringify(params.collectionHints || []),
8645
+ field_hints_json_array: JSON.stringify(params.fieldHints || [])
8646
+ };
8647
+ var userPrompt = applyTemplate(AI_ASSISTANT_PLANNER_USER_PROMPT_TEMPLATE, templateData);
8648
+ return "System:\n".concat(AI_ASSISTANT_PLANNER_SYSTEM_PROMPT, "\n\nUser:\n").concat(userPrompt).trim();
8649
+ }
8368
8650
  function buildAssistantContext(input, userContext) {
8369
8651
  var _a, _b, _c, _d, _e, _f;
8370
8652
  var lines = [];
@@ -8520,14 +8802,14 @@ function normalizeRouteMatchKey(value) {
8520
8802
  return normalizeRouteKey(value).toLowerCase();
8521
8803
  }
8522
8804
  function buildClientRouteIndex() {
8523
- var e_26, _a;
8805
+ var e_27, _a;
8524
8806
  var _b;
8525
8807
  var routes = ((_b = resolveio_server_app_1.ResolveIOServer.getClientRoutes) === null || _b === void 0 ? void 0 : _b.call(resolveio_server_app_1.ResolveIOServer)) || [];
8526
8808
  var set = new Set();
8527
8809
  var map = new Map();
8528
8810
  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;
8811
+ for (var routes_2 = __values(routes), routes_2_1 = routes_2.next(); !routes_2_1.done; routes_2_1 = routes_2.next()) {
8812
+ var route = routes_2_1.value;
8531
8813
  var normalized = normalizeRouteKey(route);
8532
8814
  if (!normalized) {
8533
8815
  continue;
@@ -8539,12 +8821,12 @@ function buildClientRouteIndex() {
8539
8821
  }
8540
8822
  }
8541
8823
  }
8542
- catch (e_26_1) { e_26 = { error: e_26_1 }; }
8824
+ catch (e_27_1) { e_27 = { error: e_27_1 }; }
8543
8825
  finally {
8544
8826
  try {
8545
- if (routes_1_1 && !routes_1_1.done && (_a = routes_1.return)) _a.call(routes_1);
8827
+ if (routes_2_1 && !routes_2_1.done && (_a = routes_2.return)) _a.call(routes_2);
8546
8828
  }
8547
- finally { if (e_26) throw e_26.error; }
8829
+ finally { if (e_27) throw e_27.error; }
8548
8830
  }
8549
8831
  return { set: set, map: map, size: routes.length };
8550
8832
  }
@@ -8691,7 +8973,7 @@ function sanitizeAssistantResponse(value) {
8691
8973
  return normalizeAssistantRoutes(normalizedCurrency);
8692
8974
  }
8693
8975
  function evaluateAssistantGuardrails(message) {
8694
- var e_27, _a;
8976
+ var e_28, _a;
8695
8977
  var normalized = String(message || '').toLowerCase();
8696
8978
  var patterns = [
8697
8979
  {
@@ -8737,12 +9019,12 @@ function evaluateAssistantGuardrails(message) {
8737
9019
  }
8738
9020
  }
8739
9021
  }
8740
- catch (e_27_1) { e_27 = { error: e_27_1 }; }
9022
+ catch (e_28_1) { e_28 = { error: e_28_1 }; }
8741
9023
  finally {
8742
9024
  try {
8743
9025
  if (patterns_1_1 && !patterns_1_1.done && (_a = patterns_1.return)) _a.call(patterns_1);
8744
9026
  }
8745
- finally { if (e_27) throw e_27.error; }
9027
+ finally { if (e_28) throw e_28.error; }
8746
9028
  }
8747
9029
  return null;
8748
9030
  }
@@ -8857,7 +9139,7 @@ function tokenizeArithmeticExpression(expression) {
8857
9139
  return tokens;
8858
9140
  }
8859
9141
  function evaluateArithmeticExpression(expression) {
8860
- var e_28, _a, e_29, _b;
9142
+ var e_29, _a, e_30, _b;
8861
9143
  var tokens = tokenizeArithmeticExpression(expression);
8862
9144
  if (!tokens || !tokens.length) {
8863
9145
  return null;
@@ -8914,12 +9196,12 @@ function evaluateArithmeticExpression(expression) {
8914
9196
  prevToken = token;
8915
9197
  }
8916
9198
  }
8917
- catch (e_28_1) { e_28 = { error: e_28_1 }; }
9199
+ catch (e_29_1) { e_29 = { error: e_29_1 }; }
8918
9200
  finally {
8919
9201
  try {
8920
9202
  if (tokens_1_1 && !tokens_1_1.done && (_a = tokens_1.return)) _a.call(tokens_1);
8921
9203
  }
8922
- finally { if (e_28) throw e_28.error; }
9204
+ finally { if (e_29) throw e_29.error; }
8923
9205
  }
8924
9206
  while (ops.length) {
8925
9207
  var op = ops.pop();
@@ -8959,12 +9241,12 @@ function evaluateArithmeticExpression(expression) {
8959
9241
  stack.push(Number(token));
8960
9242
  }
8961
9243
  }
8962
- catch (e_29_1) { e_29 = { error: e_29_1 }; }
9244
+ catch (e_30_1) { e_30 = { error: e_30_1 }; }
8963
9245
  finally {
8964
9246
  try {
8965
9247
  if (output_1_1 && !output_1_1.done && (_b = output_1.return)) _b.call(output_1);
8966
9248
  }
8967
- finally { if (e_29) throw e_29.error; }
9249
+ finally { if (e_30) throw e_30.error; }
8968
9250
  }
8969
9251
  if (stack.length !== 1 || Number.isNaN(stack[0])) {
8970
9252
  return null;
@@ -9148,8 +9430,8 @@ function handleCodexUpload(id_conversation, file_name, content_base64, size, con
9148
9430
  }
9149
9431
  function readAttachmentContents(attachments) {
9150
9432
  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;
9433
+ 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;
9434
+ var e_31, _b;
9153
9435
  return __generator(this, function (_c) {
9154
9436
  switch (_c.label) {
9155
9437
  case 0:
@@ -9228,14 +9510,14 @@ function readAttachmentContents(attachments) {
9228
9510
  return [3 /*break*/, 2];
9229
9511
  case 10: return [3 /*break*/, 13];
9230
9512
  case 11:
9231
- e_30_1 = _c.sent();
9232
- e_30 = { error: e_30_1 };
9513
+ e_31_1 = _c.sent();
9514
+ e_31 = { error: e_31_1 };
9233
9515
  return [3 /*break*/, 13];
9234
9516
  case 12:
9235
9517
  try {
9236
9518
  if (attachments_1_1 && !attachments_1_1.done && (_b = attachments_1.return)) _b.call(attachments_1);
9237
9519
  }
9238
- finally { if (e_30) throw e_30.error; }
9520
+ finally { if (e_31) throw e_31.error; }
9239
9521
  return [7 /*endfinally*/];
9240
9522
  case 13: return [2 /*return*/, {
9241
9523
  promptText: chunks.length ? "\n\nAttachments:\n".concat(chunks.join('\n\n')) : '',
@@ -9423,7 +9705,7 @@ function estimateUsage(messages, responseText, model) {
9423
9705
  };
9424
9706
  }
9425
9707
  function evaluateGuardrails(message) {
9426
- var e_31, _a;
9708
+ var e_32, _a;
9427
9709
  var normalized = String(message || '').toLowerCase();
9428
9710
  var patterns = [
9429
9711
  { 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 +9727,12 @@ function evaluateGuardrails(message) {
9445
9727
  }
9446
9728
  }
9447
9729
  }
9448
- catch (e_31_1) { e_31 = { error: e_31_1 }; }
9730
+ catch (e_32_1) { e_32 = { error: e_32_1 }; }
9449
9731
  finally {
9450
9732
  try {
9451
9733
  if (patterns_2_1 && !patterns_2_1.done && (_a = patterns_2.return)) _a.call(patterns_2);
9452
9734
  }
9453
- finally { if (e_31) throw e_31.error; }
9735
+ finally { if (e_32) throw e_32.error; }
9454
9736
  }
9455
9737
  return null;
9456
9738
  }