{{-- Flash success --}} @if(session('success'))
{{ session('success') }}
@endif @php $sensitiveKeys = ['openai_api_key', 'anthropic_api_key', 'gemini_api_key', 'mistral_api_key', 'pinecone_api_key', 'smtp_password']; $getSetting = function($key, $default = '') use ($sensitiveKeys) { static $cache = null; if ($cache === null) { try { $cache = \Illuminate\Support\Facades\DB::table('system_settings')->pluck('value', 'key')->toArray(); } catch (\Exception $e) { $cache = []; } } $value = $cache[$key] ?? $default; // Decrypt sensitive values if (in_array($key, $sensitiveKeys) && !empty($value) && $value !== $default) { try { $value = decrypt($value); } catch (\Exception $e) { // Value may not be encrypted yet (legacy data), return as-is } } return $value; }; // Load AI usage stats per provider from db $providerStats = []; try { $providerStats = \Illuminate\Support\Facades\DB::table('ai_usage_logs') ->selectRaw("provider, COUNT(*) as requests, COALESCE(SUM(cost), 0) as cost, COALESCE(SUM(tokens_in + tokens_out), 0) as tokens") ->groupBy('provider') ->pluck(null, 'provider') ->toArray(); } catch (\Exception $e) { // ignore } $formatTokens = function($t) { if ($t >= 1000000) return number_format($t / 1000000, 1) . 'M'; if ($t >= 1000) return number_format($t / 1000, 1) . 'K'; return number_format($t); }; @endphp {{-- Default Provider & Model Selection --}}
@csrf

{{ __('Default Configuration') }}

{{ __('Set the default AI provider and model for all workspaces') }}

{{-- AI Provider Cards --}}

{{ __('Language Model Providers') }}

@php $providers = [ [ 'name' => 'OpenAI', 'key' => 'openai', 'setting_key' => 'openai_api_key', 'desc' => __('GPT-4o, GPT-4 Turbo, o1/o3 Reasoning'), 'gradient' => 'from-green-500 to-emerald-600', 'shadow' => 'shadow-green-200', 'abbr' => 'AI', 'models' => ['gpt-4o', 'gpt-4o-mini', 'gpt-4-turbo', 'o1-mini', 'o3-mini', 'text-embedding-3-large'], 'model_colors' => ['bg-brand/15 text-brand', 'bg-brand/10 text-brand', 'bg-brand/10 text-brand', 'bg-brand/10 text-brand', 'bg-surface text-muted', 'bg-surface text-muted'], 'stat_colors' => ['bg-success/10 border-success/20 text-success', 'bg-warning/10 border-warning/20 text-warning', 'bg-info/10 border-info/20 text-info'], ], [ 'name' => 'Anthropic', 'key' => 'anthropic', 'setting_key' => 'anthropic_api_key', 'desc' => __('Claude Sonnet 4, Opus 4, Haiku'), 'gradient' => 'from-amber-600 to-orange-700', 'shadow' => 'shadow-amber-500/20', 'abbr' => 'An', 'models' => ['claude-sonnet-4-20250514', 'claude-opus-4-20250514', 'claude-haiku-4-5-20251001'], 'model_colors' => ['bg-warning/15 text-warning', 'bg-warning/10 text-warning', 'bg-surface text-muted'], 'stat_colors' => ['bg-warning/10 border-warning/20 text-warning', 'bg-warning/10 border-warning/20 text-warning', 'bg-warning/10 border-warning/20 text-warning'], ], [ 'name' => 'Google Gemini', 'key' => 'gemini', 'setting_key' => 'gemini_api_key', 'desc' => __('Gemini 2.0 Flash, Gemini Pro'), 'gradient' => 'from-blue-500 to-cyan-600', 'shadow' => 'shadow-blue-500/20', 'abbr' => 'Gm', 'models' => ['gemini-2.0-flash', 'gemini-1.5-pro', 'gemini-1.5-flash'], 'model_colors' => ['bg-info/15 text-info', 'bg-info/10 text-info', 'bg-surface text-muted'], 'stat_colors' => ['bg-info/10 border-info/20 text-info', 'bg-info/10 border-info/20 text-info', 'bg-info/10 border-info/20 text-info'], ], [ 'name' => 'Mistral', 'key' => 'mistral', 'setting_key' => 'mistral_api_key', 'desc' => __('Mistral Large, Medium, Small'), 'gradient' => 'from-rose-500 to-pink-600', 'shadow' => 'shadow-rose-500/20', 'abbr' => 'Mi', 'models' => ['mistral-large-latest', 'mistral-medium-latest', 'mistral-small-latest'], 'model_colors' => ['bg-danger/15 text-danger', 'bg-danger/10 text-danger', 'bg-surface text-muted'], 'stat_colors' => ['bg-danger/10 border-danger/20 text-danger', 'bg-danger/10 border-danger/20 text-danger', 'bg-danger/10 border-danger/20 text-danger'], ], ]; @endphp @foreach($providers as $p) @php $apiKeyVal = $getSetting($p['setting_key'], ''); $hasKey = !empty($apiKeyVal); $pStats = $providerStats[$p['key']] ?? null; @endphp
@csrf
{{ $p['abbr'] }}

{{ $p['name'] }}

{{ $p['desc'] }}

@if($hasKey) {{ __('Key Saved') }} @else {{ __('Not Connected') }} @endif
{{-- API Key --}}

{{ $hasKey ? __('A key is already saved. Enter a new key to replace it, or leave blank to keep the current key.') : __('Keys are validated when first used. Save your key to enable this provider.') }}

{{-- Models --}}
@foreach($p['models'] as $idx => $model) {{ $model }} @endforeach
{{-- Usage stats from real data --}}

{{ __('Requests') }}

{{ $pStats ? number_format($pStats->requests) : '--' }}

{{ __('Cost') }}

@if($pStats) @currency($pStats->cost) @else -- @endif

{{ __('Tokens') }}

{{ $pStats ? $formatTokens($pStats->tokens) : '--' }}

{{-- Save --}}
@endforeach
{{-- Vector Database --}}

{{ __('Vector Database') }}

{{-- Pinecone --}}
@csrf
Pc

Pinecone

{{ __('Vector database for embeddings') }}

@php $pineconeKey = $getSetting('pinecone_api_key', ''); @endphp @if(!empty($pineconeKey)) {{ __('Key Saved') }} @else {{ __('Not Connected') }} @endif

{{ !empty($pineconeKey) ? __('A key is already saved. Enter a new key to replace it, or leave blank to keep the current key.') : __('Save your key to enable Pinecone.') }}

{{ __('Connection is validated when first used. Save your settings to enable Pinecone.') }}

{{-- AI Cost Summary from real data --}}

{{ __('AI Cost Summary') }}

{{ __('Total AI spend from usage logs') }}

@php $totalAiCost = 0; @endphp
@forelse($providerStats as $pName => $pData) @php $totalAiCost += $pData->cost; @endphp
{{ ucfirst($pName) }} @currency($pData->cost)
@empty
{{ __('No AI usage recorded yet.') }}
@endforelse @if(!empty($providerStats))
{{ __('Total') }} @currency($totalAiCost)
@endif
@php $aiBudget = (float) $getSetting('ai_monthly_budget', '500'); $budgetPercent = $aiBudget > 0 ? min(round(($totalAiCost / $aiBudget) * 100), 100) : 0; @endphp
{{ __('Budget Used') }} {{ $budgetPercent }}%

@currency($totalAiCost) {{ __('of') }} @currency($aiBudget) {{ __('monthly budget') }}