diff --git a/apps/rebreak-native/components/urge/LlmProviderToggle.tsx b/apps/rebreak-native/components/urge/LlmProviderToggle.tsx index d921a6a..ff7f968 100644 --- a/apps/rebreak-native/components/urge/LlmProviderToggle.tsx +++ b/apps/rebreak-native/components/urge/LlmProviderToggle.tsx @@ -1,7 +1,7 @@ import { Pressable, Text, View } from 'react-native'; import { LLM_PROVIDER_LABEL, type LlmProvider, useLlmProvider } from '../../lib/llmProvider'; -const PROVIDERS: LlmProvider[] = ['openrouter-sonnet', 'openrouter-haiku', 'groq-llama']; +const PROVIDERS: LlmProvider[] = ['auto', 'openrouter-sonnet', 'openrouter-haiku', 'groq-llama']; export function LlmProviderToggle() { const [current, set] = useLlmProvider(); diff --git a/apps/rebreak-native/lib/llmProvider.ts b/apps/rebreak-native/lib/llmProvider.ts index 8ad44b8..3fb32ba 100644 --- a/apps/rebreak-native/lib/llmProvider.ts +++ b/apps/rebreak-native/lib/llmProvider.ts @@ -6,12 +6,15 @@ import AsyncStorage from '@react-native-async-storage/async-storage'; import { useEffect, useState } from 'react'; -export type LlmProvider = 'openrouter-sonnet' | 'openrouter-haiku' | 'groq-llama'; +export type LlmProvider = 'auto' | 'openrouter-sonnet' | 'openrouter-haiku' | 'groq-llama'; const STORAGE_KEY = 'rebreak-sos-llm-provider'; -const DEFAULT_PROVIDER: LlmProvider = 'openrouter-sonnet'; +// Default 'auto' → backend wählt nach plan: Pro=Groq, Legend=Haiku, Free=Groq. +// Explicit-Toggles (Sonnet/Haiku/Groq) sind debug-overrides und bypassen plan-logic. +const DEFAULT_PROVIDER: LlmProvider = 'auto'; export const LLM_PROVIDER_LABEL: Record = { + auto: 'Auto', 'openrouter-sonnet': 'Sonnet', 'openrouter-haiku': 'Haiku', 'groq-llama': 'Groq', @@ -24,7 +27,9 @@ export async function loadLlmProvider(): Promise { if (cached) return cached; const raw = await AsyncStorage.getItem(STORAGE_KEY).catch(() => null); cached = - raw === 'openrouter-haiku' || raw === 'groq-llama' ? raw : DEFAULT_PROVIDER; + raw === 'auto' || raw === 'openrouter-sonnet' || raw === 'openrouter-haiku' || raw === 'groq-llama' + ? raw + : DEFAULT_PROVIDER; return cached; } diff --git a/backend/server/api/coach/sos-stream.get.ts b/backend/server/api/coach/sos-stream.get.ts index 8dad30f..94f94ef 100644 --- a/backend/server/api/coach/sos-stream.get.ts +++ b/backend/server/api/coach/sos-stream.get.ts @@ -152,7 +152,17 @@ export default defineEventHandler(async (event) => { // LLM-Routing: client schickt llmProvider via /sos-session-Body (Toggle). // Default openrouter-sonnet. sort:latency bei Anthropic über OR spart 30-58% TTFB // (server-curl-bench gemessen). Groq bypasst OpenRouter-Hop für ~157ms TTFB. - const llmProvider = sessionData.llmProvider ?? "openrouter-sonnet"; + // Tier-based LLM: Pro=Groq (sachlich+schnell), Legend=Haiku 4.5 (warm+fast), + // Free=Groq (kostenkontrolle). User kann via Toggle override (debug); + // 'auto' (oder undefined) → plan-based default. + const userToggle = sessionData.llmProvider; + let llmProvider: string; + if (userToggle && userToggle !== "auto") { + llmProvider = userToggle; + } else { + const plan = ((profile as any)?.plan ?? "free").toLowerCase(); + llmProvider = plan === "legend" ? "openrouter-haiku" : "groq-llama"; + } let upstreamUrl: string; let upstreamKey: string | undefined; let upstreamModel: string;