$requestedEngine, 'plus' => $requestedEngine === 'azure_full' ? 'azure_mini' : $requestedEngine, default => in_array($requestedEngine, ['nova_lite', 'regex'], true) ? $requestedEngine : 'nova_lite', }; } public static function timelineRoute(int $userId, string $requestedEngine, string $text): array { $valid = ['nova_lite', 'azure_mini', 'azure_full']; $requestedEngine = in_array($requestedEngine, $valid, true) ? $requestedEngine : 'azure_mini'; $tierEngine = self::engineForUser($userId, $requestedEngine); $charCount = mb_strlen($text, 'UTF-8'); if ($charCount > self::TIMELINE_DEEP_CHAR_LIMIT) { throw new DbnToolsHttpException( 'This timeline input is too large after selected documents or My Case context were added. Split the file or use fewer selected documents.', 413, 'timeline_input_too_large', ['input_char_count' => $charCount, 'max_chars' => self::TIMELINE_DEEP_CHAR_LIMIT] ); } $effectiveEngine = $tierEngine; if ($charCount > self::TIMELINE_STANDARD_CHAR_LIMIT) { $effectiveEngine = 'azure_full'; } elseif ($charCount > self::TIMELINE_QUICK_CHAR_LIMIT && $effectiveEngine === 'nova_lite') { $effectiveEngine = 'azure_mini'; } return [ 'requested_engine' => $requestedEngine, 'tier_engine' => $tierEngine, 'effective_engine' => $effectiveEngine, 'auto_upgraded_engine' => $effectiveEngine !== $tierEngine, 'input_char_count' => $charCount, 'engine_limit_chars' => self::timelineEngineLimit($effectiveEngine), 'credits' => self::timelineCredits($effectiveEngine), ]; } public static function timelineCredits(string $engine): int { return $engine === 'azure_full' ? 2 : 1; } public static function timelineEngineLimit(string $engine): int { return match ($engine) { 'nova_lite' => self::TIMELINE_QUICK_CHAR_LIMIT, 'azure_mini' => self::TIMELINE_STANDARD_CHAR_LIMIT, default => self::TIMELINE_DEEP_CHAR_LIMIT, }; } }