'azure'|'bedrock', 'model' => string|null]. * gateway='azure' means always use Azure regardless of DBN_BEDROCK_ENABLED. * gateway='bedrock' means use Bedrock when enabled, fall back to Azure when not. * model is null for azure-pinned tools (caller uses DbnAzureOpenAiGateway directly). */ public static function routeForTool(string $tool, string $tier = 'free'): array { $tier = in_array($tier, ['free', 'plus', 'pro'], true) ? $tier : 'free'; if (in_array($tool, self::AZURE_PINNED, true)) { return ['gateway' => 'azure', 'model' => null]; } if (in_array($tool, self::HAIKU_TOOLS, true)) { // Pro users get Sonnet for these tools; free/plus get Haiku $model = ($tier === 'pro') ? self::LITELLM_SONNET : self::LITELLM_HAIKU; return ['gateway' => 'bedrock', 'model' => $model]; } // All drafting/reasoning tools → Sonnet (korrespond, legal-analysis, deep-research, // barnevernet-analyze, discrepancy-find, advocate) return ['gateway' => 'bedrock', 'model' => self::LITELLM_SONNET]; } /** @deprecated Use routeForTool() — kept for any direct callers outside the factory. */ public static function modelForTool(string $tool, string $tier = 'free'): string { $route = self::routeForTool($tool, $tier); return $route['model'] ?? self::LITELLM_SONNET; } /** * Maps a quality-tier engine string to the LiteLLM deployment name passed to * withDeployment(). claude_haiku/claude_sonnet route to Bedrock Claude when the * active gateway is Bedrock; otherwise they degrade to the Azure GPT-4o family. */ public static function deploymentForEngine(string $engine, bool $isBedrock): string { switch ($engine) { case 'claude_sonnet': return $isBedrock ? self::LITELLM_SONNET : 'gpt-4o'; case 'claude_haiku': return $isBedrock ? self::LITELLM_HAIKU : 'gpt-4o-mini'; case 'azure_full': return 'gpt-4o'; case 'azure_mini': default: return 'gpt-4o-mini'; } } public static function supportsThinking(string $modelName): bool { return in_array($modelName, self::THINKING_MODELS, true); } public static function maxTokensForTool(string $tool): int { return match ($tool) { 'deep-research', 'barnevernet-analyze', 'advocate' => 4000, 'legal-analysis', 'korrespond', 'discrepancy-find' => 3000, default => 2000, }; } }