'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; } 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, }; } }