82 lines
3.1 KiB
PHP
82 lines
3.1 KiB
PHP
<?php
|
|
declare(strict_types=1);
|
|
|
|
require_once __DIR__ . '/FreeTier.php';
|
|
|
|
/**
|
|
* Tier-aware model routing for tools that expose the existing engine selector.
|
|
*
|
|
* Plus/trial users get the cost-controlled Azure mini path. Pro users get the
|
|
* full Azure path. CaveauAI sessions keep the engine requested by their UI.
|
|
*/
|
|
final class ToolModels
|
|
{
|
|
public const TIMELINE_QUICK_CHAR_LIMIT = 25000;
|
|
public const TIMELINE_STANDARD_CHAR_LIMIT = 55000;
|
|
public const TIMELINE_DEEP_CHAR_LIMIT = 128000;
|
|
|
|
public static function engineForUser(int $userId, string $requestedEngine): string
|
|
{
|
|
$valid = ['nova_lite', 'azure_mini', 'azure_full', 'gpu', 'regex'];
|
|
$requestedEngine = in_array($requestedEngine, $valid, true) ? $requestedEngine : 'azure_mini';
|
|
|
|
if ($userId <= 0) {
|
|
return $requestedEngine;
|
|
}
|
|
|
|
return match (FreeTier::tier($userId)) {
|
|
'pro' => $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,
|
|
};
|
|
}
|
|
}
|