From 929de621e6c51018f9a93f1367f59e88e93ca323 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Ak=C4=B1n?= Date: Tue, 8 Sep 2026 21:45:04 +0300 Subject: [PATCH 1/2] feat: add ModelRunner as a chat provider MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ModelRunner serves an OpenAI-compatible chat surface, so it needs no new adapter: OpenAIAdapter already composes `{base}/chat/completions` from a base URL ending in `/v1`, and the trait's default `list_models_endpoint` / `parse_models_list` handle its discovery list unchanged. The dispatch arm is written out rather than left to the `_` fallback, matching how lettuce-host is registered. Everything else is the surrounding wiring one provider needs: the config tuple, the onboarding default base URL in both reducers, the aggregator description bucket, the icon, the parameter-support profile, and the key-location guide. The parameter profile mirrors the Mistral one — the surface forwards the standard OpenAI sampling parameters to the model and exposes no reasoning toggle of its own, so reasoningSupport is "none" rather than a claim the backend cannot honour. Deliberately NOT added to `supports_model_list` in models/verify.rs: the discovery list is public models only, while a key can also call private ones, and `exists: false` there blocks the save outright. The default (skip the check) is the correct behaviour for this provider rather than an oversight. Guide copy is English only. translateWithLocale() falls back to the English tree for a missing key, so every locale renders it; the other 20 should come from speakers of those languages rather than from me. Co-Authored-By: Claude Opus 5 --- .../src/chat_manager/provider_adapter/mod.rs | 1 + src-tauri/src/providers/config.rs | 1 + src/assets/modelrunner.png | Bin 0 -> 15555 bytes src/core/i18n/locales/en.ts | 7 +++ src/core/storage/schemas.ts | 51 ++++++++++++++++++ src/core/utils/providerIcons.tsx | 2 + src/ui/pages/onboarding/ProviderSetup.tsx | 2 + src/ui/pages/onboarding/WhereToFind.tsx | 5 ++ .../onboarding/components/ProviderCard.tsx | 2 + .../onboarding/hooks/onboardingReducer.ts | 2 + .../pages/onboarding/hooks/providerReducer.ts | 2 + 11 files changed, 75 insertions(+) create mode 100644 src/assets/modelrunner.png diff --git a/src-tauri/src/chat_manager/provider_adapter/mod.rs b/src-tauri/src/chat_manager/provider_adapter/mod.rs index 21a697a5a..223cd0e0b 100644 --- a/src-tauri/src/chat_manager/provider_adapter/mod.rs +++ b/src-tauri/src/chat_manager/provider_adapter/mod.rs @@ -372,6 +372,7 @@ pub fn adapter_for(credential: &ProviderCredential) -> Box Box::new(openai::OpenRouterAdapter), "literouter" => Box::new(literouter::LiteRouterAdapter), "pollinations" => Box::new(pollinations::PollinationsAdapter), + "modelrunner" => Box::new(openai::OpenAIAdapter), "lettuce-host" => Box::new(openai::OpenAIAdapter), "lettuce-engine" => Box::new(lettuce_engine::LettuceEngineAdapter), _ => Box::new(openai::OpenAIAdapter), diff --git a/src-tauri/src/providers/config.rs b/src-tauri/src/providers/config.rs index 1adf46e6c..cae2185b1 100644 --- a/src-tauri/src/providers/config.rs +++ b/src-tauri/src/providers/config.rs @@ -161,6 +161,7 @@ fn get_all_provider_configs_internal() -> Vec { "https://integrate.api.nvidia.com/v1", ), ("anannas", "Anannas AI", "https://api.anannas.ai/v1"), + ("modelrunner", "ModelRunner", "https://queue.modelrunner.run/v1"), ("groq", "Groq", "https://api.groq.com"), ("stability", "Stability AI", "https://api.stability.ai"), ( diff --git a/src/assets/modelrunner.png b/src/assets/modelrunner.png new file mode 100644 index 0000000000000000000000000000000000000000..ed9dac22210773ceac80f8a22d0dd41ec7ac67fd GIT binary patch literal 15555 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 literal 0 HcmV?d00001 diff --git a/src/core/i18n/locales/en.ts b/src/core/i18n/locales/en.ts index 70e5b1c27..f61962014 100644 --- a/src/core/i18n/locales/en.ts +++ b/src/core/i18n/locales/en.ts @@ -8703,6 +8703,13 @@ export const enMessages = { s3: "Create a new key if you do not see one.", s4: "Copy the key and paste it into LettuceAI.", }, + modelrunner: { + title: "How to find your ModelRunner API key", + s1: "Visit modelrunner.ai and sign in.", + s2: "Open Settings, then API Keys.", + s3: "Create a new key if you do not see one.", + s4: "Copy the key and paste it into LettuceAI.", + }, anannas: { title: "How to find your Anannas API key", s1: "Go to dashboard.anannas.ai and log in.", diff --git a/src/core/storage/schemas.ts b/src/core/storage/schemas.ts index 5afc8fc1a..79f91532c 100644 --- a/src/core/storage/schemas.ts +++ b/src/core/storage/schemas.ts @@ -2037,6 +2037,57 @@ export const PROVIDER_PARAMETER_SUPPORT = { ollamaStop: false, }, }, + + modelrunner: { + providerId: "modelrunner", + displayName: "ModelRunner", + reasoningSupport: "none" as ReasoningSupport, + supportedParameters: { + temperature: true, + topP: true, + maxOutputTokens: true, + contextLength: false, + frequencyPenalty: true, + presencePenalty: true, + topK: false, + reasoningEnabled: false, + reasoningEffort: false, + reasoningBudgetTokens: false, + llamaGpuLayers: false, + llamaThreads: false, + llamaThreadsBatch: false, + llamaSeed: false, + llamaRopeFreqBase: false, + llamaRopeFreqScale: false, + llamaOffloadKqv: false, + llamaBatchSize: false, + llamaKvType: false, + llamaFlashAttention: false, + llamaChatTemplateOverride: false, + llamaMmprojPath: false, + llamaChatTemplatePreset: false, + llamaRawCompletionFallback: false, + llamaSamplerProfile: false, + llamaSamplerOrder: false, + llamaMinP: false, + llamaTypicalP: false, + ollamaNumCtx: false, + ollamaNumPredict: false, + ollamaNumKeep: false, + ollamaNumBatch: false, + ollamaNumGpu: false, + ollamaNumThread: false, + ollamaTfsZ: false, + ollamaTypicalP: false, + ollamaMinP: false, + ollamaMirostat: false, + ollamaMirostatTau: false, + ollamaMirostatEta: false, + ollamaRepeatPenalty: false, + ollamaSeed: false, + ollamaStop: false, + }, + }, ollama: { providerId: "ollama", displayName: "Ollama", diff --git a/src/core/utils/providerIcons.tsx b/src/core/utils/providerIcons.tsx index 516e4f141..e9aa81d0b 100644 --- a/src/core/utils/providerIcons.tsx +++ b/src/core/utils/providerIcons.tsx @@ -25,6 +25,7 @@ import MoonShotAIIcon from "../../assets/moonshot_light.svg"; import GeminiIcon from "../../assets/gemini.svg"; import QwenIcon from "../../assets/qwen.svg"; import FeatherlessIcon from "../../assets/featherless.svg"; +import ModelRunnerIcon from "../../assets/modelrunner.png"; import NvidiaIcon from "../../assets/nvidia.svg"; import ChutesAIIcon from "../../assets/chutes_ai.jpeg"; import OllamaIcon from "../../assets/ollama_light.png"; @@ -55,6 +56,7 @@ const ICON_MAP: Record = { qwen: Qwen, groq: Groq, featherless: Featherless, + modelrunner: ModelRunner, nvidia: NVIDIA, chutes: Chutes, ollama: Ollama, diff --git a/src/ui/pages/onboarding/ProviderSetup.tsx b/src/ui/pages/onboarding/ProviderSetup.tsx index ae47ab269..f5ef2c3aa 100644 --- a/src/ui/pages/onboarding/ProviderSetup.tsx +++ b/src/ui/pages/onboarding/ProviderSetup.tsx @@ -452,6 +452,7 @@ function getProviderDescription(providerId: string, t: TFunction): string { return t("onboarding.provider.descriptions.anthropic"); case "nanogpt": case "featherless": + case "modelrunner": case "openrouter": return t("onboarding.provider.descriptions.aggregator"); case "openai-compatible": @@ -491,6 +492,7 @@ function getProviderDescriptionShort(providerId: string, t: TFunction): string { return t("onboarding.provider.descriptionsShort.anthropic"); case "nanogpt": case "featherless": + case "modelrunner": case "openrouter": return t("onboarding.provider.descriptionsShort.aggregator"); case "openai-compatible": diff --git a/src/ui/pages/onboarding/WhereToFind.tsx b/src/ui/pages/onboarding/WhereToFind.tsx index 953382872..97610881f 100644 --- a/src/ui/pages/onboarding/WhereToFind.tsx +++ b/src/ui/pages/onboarding/WhereToFind.tsx @@ -99,6 +99,11 @@ function buildGuides(t: TFunction): Record { steps: guideSteps("featherless"), url: "https://featherless.ai/", }, + modelrunner: { + title: guideTitle("modelrunner"), + steps: guideSteps("modelrunner"), + url: "https://modelrunner.ai/settings/api-keys", + }, anannas: { title: guideTitle("anannas"), steps: guideSteps("anannas"), diff --git a/src/ui/pages/onboarding/components/ProviderCard.tsx b/src/ui/pages/onboarding/components/ProviderCard.tsx index e1fdf2fd8..bc7772a3b 100644 --- a/src/ui/pages/onboarding/components/ProviderCard.tsx +++ b/src/ui/pages/onboarding/components/ProviderCard.tsx @@ -114,6 +114,7 @@ function getProviderDescription(providerId: string, t: TFunction): string { return t("onboarding.provider.descriptions.anthropic"); case "nanogpt": case "featherless": + case "modelrunner": case "openrouter": return t("onboarding.provider.descriptions.aggregator"); case "openai-compatible": @@ -155,6 +156,7 @@ function getProviderDescriptionShort(providerId: string, t: TFunction): string { return t("onboarding.provider.descriptionsShort.anthropic"); case "nanogpt": case "featherless": + case "modelrunner": case "openrouter": return t("onboarding.provider.descriptionsShort.aggregator"); case "openai-compatible": diff --git a/src/ui/pages/onboarding/hooks/onboardingReducer.ts b/src/ui/pages/onboarding/hooks/onboardingReducer.ts index 5df6517e1..e44c163d7 100644 --- a/src/ui/pages/onboarding/hooks/onboardingReducer.ts +++ b/src/ui/pages/onboarding/hooks/onboardingReducer.ts @@ -221,6 +221,8 @@ export function getDefaultBaseUrl(providerId: string): string { return "https://llm.chutes.ai"; case "featherless": return "https://api.featherless.ai/v1"; + case "modelrunner": + return "https://queue.modelrunner.run/v1"; case "openrouter": return "https://openrouter.ai/api"; case "openai": diff --git a/src/ui/pages/onboarding/hooks/providerReducer.ts b/src/ui/pages/onboarding/hooks/providerReducer.ts index 036910c17..325402338 100644 --- a/src/ui/pages/onboarding/hooks/providerReducer.ts +++ b/src/ui/pages/onboarding/hooks/providerReducer.ts @@ -70,6 +70,8 @@ export function getDefaultBaseUrl(providerId: string): string { return "https://llm.chutes.ai"; case "featherless": return "https://api.featherless.ai/v1"; + case "modelrunner": + return "https://queue.modelrunner.run/v1"; case "openrouter": return "https://openrouter.ai/api"; case "openai": From 85994e2b53b6b54e56699d46507a0db1011f7516 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kaan=20Ak=C4=B1n?= Date: Wed, 9 Sep 2026 17:42:43 +0300 Subject: [PATCH 2/2] i18n: add the ModelRunner key guide to the remaining 19 locales MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each entry follows its own file rather than a generic translation: title and s1 keep that locale's existing featherless wording with the brand and domain swapped, and s3/s4 are lifted verbatim from the same block, so register stays consistent per file (du/Sie, tu/vous, formal/informal) instead of being re-decided by me. s2 is the only genuinely new sentence. "Settings" and "API Keys" stay English in every locale because that settings page is English-only — they are the words the reader will see on screen. Three neighbours were not usable as a source and are written out instead: pt and vi carry the whole guides section in English, and tr's featherless entry translates the brand ("tüysüz.ai"), which points at a site that does not exist. Those pre-existing entries are left untouched here. These are drafts by a non-native speaker; corrections welcome. Co-Authored-By: Claude Opus 5 --- src/core/i18n/locales/de.ts | 7 +++++++ src/core/i18n/locales/el.ts | 7 +++++++ src/core/i18n/locales/es.ts | 7 +++++++ src/core/i18n/locales/fil.ts | 7 +++++++ src/core/i18n/locales/fr.ts | 7 +++++++ src/core/i18n/locales/hi.ts | 7 +++++++ src/core/i18n/locales/id.ts | 7 +++++++ src/core/i18n/locales/it.ts | 7 +++++++ src/core/i18n/locales/ja.ts | 7 +++++++ src/core/i18n/locales/ko.ts | 7 +++++++ src/core/i18n/locales/nl.ts | 7 +++++++ src/core/i18n/locales/no.ts | 7 +++++++ src/core/i18n/locales/pl.ts | 7 +++++++ src/core/i18n/locales/pt.ts | 7 +++++++ src/core/i18n/locales/ru.ts | 7 +++++++ src/core/i18n/locales/tr.ts | 7 +++++++ src/core/i18n/locales/vi.ts | 7 +++++++ src/core/i18n/locales/zh-Hans.ts | 7 +++++++ src/core/i18n/locales/zh-Hant.ts | 7 +++++++ 19 files changed, 133 insertions(+) diff --git a/src/core/i18n/locales/de.ts b/src/core/i18n/locales/de.ts index 6e2367b48..8cd9b519d 100644 --- a/src/core/i18n/locales/de.ts +++ b/src/core/i18n/locales/de.ts @@ -7781,6 +7781,13 @@ export const deMessages: DeepPartialMessageTree = { s3: "Erstelle einen neuen Key, falls keiner vorhanden ist.", s4: "Kopiere den Key und füge ihn in LettuceAI ein.", }, + modelrunner: { + title: "So findest du deinen ModelRunner-API-Key", + s1: "Besuche modelrunner.ai und melde dich an.", + s2: "Öffne Settings und dann API Keys.", + s3: "Erstelle einen neuen Key, falls keiner vorhanden ist.", + s4: "Kopiere den Key und füge ihn in LettuceAI ein.", + }, anannas: { title: "So findest du deinen Anannas-API-Key", s1: "Gehe zu dashboard.anannas.ai und melde dich an.", diff --git a/src/core/i18n/locales/el.ts b/src/core/i18n/locales/el.ts index 2c0849034..e7ed08717 100644 --- a/src/core/i18n/locales/el.ts +++ b/src/core/i18n/locales/el.ts @@ -7781,6 +7781,13 @@ export const elMessages: DeepPartialMessageTree = { s3: "Δημιουργήστε νέο κλειδί αν δεν βλέπετε κανένα.", s4: "Αντιγράψτε το κλειδί και επικολλήστε το στο LettuceAI.", }, + modelrunner: { + title: "Πώς να βρείτε το κλειδί API ModelRunner", + s1: "Επισκεφτείτε το modelrunner.ai και συνδεθείτε.", + s2: "Ανοίξτε το Settings και μετά το API Keys.", + s3: "Δημιουργήστε νέο κλειδί αν δεν βλέπετε κανένα.", + s4: "Αντιγράψτε το κλειδί και επικολλήστε το στο LettuceAI.", + }, anannas: { title: "Πώς να βρείτε το κλειδί API Anannas", s1: "Μεταβείτε στο dashboard.anannas.ai και συνδεθείτε.", diff --git a/src/core/i18n/locales/es.ts b/src/core/i18n/locales/es.ts index a7ed8aab9..411d0eb84 100644 --- a/src/core/i18n/locales/es.ts +++ b/src/core/i18n/locales/es.ts @@ -7781,6 +7781,13 @@ export const esMessages: DeepPartialMessageTree = { s3: "Crea una nueva key si no ves ninguna.", s4: "Copia la key y pégala en LettuceAI.", }, + modelrunner: { + title: "Cómo encontrar tu API key de ModelRunner", + s1: "Visita modelrunner.ai e inicia sesión.", + s2: "Abre Settings y luego API Keys.", + s3: "Crea una nueva key si no ves ninguna.", + s4: "Copia la key y pégala en LettuceAI.", + }, anannas: { title: "Cómo encontrar tu API key de Anannas", s1: "Ve a dashboard.anannas.ai e inicia sesión.", diff --git a/src/core/i18n/locales/fil.ts b/src/core/i18n/locales/fil.ts index 666fd8799..0d18715ea 100644 --- a/src/core/i18n/locales/fil.ts +++ b/src/core/i18n/locales/fil.ts @@ -7781,6 +7781,13 @@ export const filMessages: DeepPartialMessageTree = { s3: "Gumawa ng bagong key kung wala kang nakita.", s4: "Kopyahin ang key at i-paste ito sa LettuceAI.", }, + modelrunner: { + title: "Paano mahanap ang iyong ModelRunner API key", + s1: "Bisitahin ang modelrunner.ai at mag-sign in.", + s2: "Buksan ang Settings, tapos ang API Keys.", + s3: "Gumawa ng bagong key kung wala kang nakita.", + s4: "Kopyahin ang key at i-paste ito sa LettuceAI.", + }, anannas: { title: "Paano mahanap ang iyong Anannas API key", s1: "Pumunta sa dashboard.anannas.ai at mag-log in.", diff --git a/src/core/i18n/locales/fr.ts b/src/core/i18n/locales/fr.ts index 6e28540e8..75d2d61c7 100644 --- a/src/core/i18n/locales/fr.ts +++ b/src/core/i18n/locales/fr.ts @@ -7781,6 +7781,13 @@ export const frMessages: DeepPartialMessageTree = { s3: "Crée une nouvelle clé si tu n'en vois pas.", s4: "Copie la clé et colle-la dans LettuceAI.", }, + modelrunner: { + title: "Comment trouver ta clé API ModelRunner", + s1: "Visite modelrunner.ai et connecte-toi.", + s2: "Ouvre Settings, puis API Keys.", + s3: "Crée une nouvelle clé si tu n'en vois pas.", + s4: "Copie la clé et colle-la dans LettuceAI.", + }, anannas: { title: "Comment trouver ta clé API Anannas", s1: "Va sur dashboard.anannas.ai et connecte-toi.", diff --git a/src/core/i18n/locales/hi.ts b/src/core/i18n/locales/hi.ts index 20d766ea4..7190a2f3b 100644 --- a/src/core/i18n/locales/hi.ts +++ b/src/core/i18n/locales/hi.ts @@ -6965,6 +6965,13 @@ export const hiMessages: DeepPartialMessageTree = { s3: "यदि आपको कोई नहीं दिखे तो एक नई key बनाएँ।", s4: "Key कॉपी करें और LettuceAI में पेस्ट करें।", }, + modelrunner: { + title: "अपनी ModelRunner API key कैसे खोजें", + s1: "modelrunner.ai पर जाएँ और साइन इन करें।", + s2: "Settings खोलें, फिर API Keys।", + s3: "यदि आपको कोई नहीं दिखे तो एक नई key बनाएँ।", + s4: "Key कॉपी करें और LettuceAI में पेस्ट करें।", + }, anannas: { title: "अपनी Anannas API key कैसे खोजें", s1: "dashboard.anannas.ai पर जाएँ और लॉग इन करें।", diff --git a/src/core/i18n/locales/id.ts b/src/core/i18n/locales/id.ts index d5d5ca577..76c276e61 100644 --- a/src/core/i18n/locales/id.ts +++ b/src/core/i18n/locales/id.ts @@ -6965,6 +6965,13 @@ export const idMessages: DeepPartialMessageTree = { s3: "Buat kunci baru jika belum ada.", s4: "Salin kunci dan tempelkan ke LettuceAI.", }, + modelrunner: { + title: "Cara menemukan kunci API ModelRunner Anda", + s1: "Kunjungi modelrunner.ai dan masuk.", + s2: "Buka Settings, lalu API Keys.", + s3: "Buat kunci baru jika belum ada.", + s4: "Salin kunci dan tempelkan ke LettuceAI.", + }, anannas: { title: "Cara menemukan kunci API Anannas Anda", s1: "Buka dashboard.anannas.ai dan masuk.", diff --git a/src/core/i18n/locales/it.ts b/src/core/i18n/locales/it.ts index c9b2b6b3d..a74d81d51 100644 --- a/src/core/i18n/locales/it.ts +++ b/src/core/i18n/locales/it.ts @@ -6965,6 +6965,13 @@ export const itMessages: DeepPartialMessageTree = { s3: "Crea una nuova chiave se non ne vedi una.", s4: "Copia la chiave e incollala in LettuceAI.", }, + modelrunner: { + title: "Come trovare la tua chiave API ModelRunner", + s1: "Visita modelrunner.ai e accedi.", + s2: "Apri Settings e poi API Keys.", + s3: "Crea una nuova chiave se non ne vedi una.", + s4: "Copia la chiave e incollala in LettuceAI.", + }, anannas: { title: "Come trovare la tua chiave API Anannas", s1: "Vai su dashboard.anannas.ai e accedi.", diff --git a/src/core/i18n/locales/ja.ts b/src/core/i18n/locales/ja.ts index c6c45230e..8d0934240 100644 --- a/src/core/i18n/locales/ja.ts +++ b/src/core/i18n/locales/ja.ts @@ -6965,6 +6965,13 @@ export const jaMessages: DeepPartialMessageTree = { s3: "見当たらない場合は新しいキーを作成します。", s4: "キーをコピーしてLettuceAIに貼り付けます。", }, + modelrunner: { + title: "ModelRunner APIキーの見つけ方", + s1: "modelrunner.aiにアクセスしてサインインします。", + s2: "Settings を開き、API Keys に移動します。", + s3: "見当たらない場合は新しいキーを作成します。", + s4: "キーをコピーしてLettuceAIに貼り付けます。", + }, anannas: { title: "Anannas APIキーの見つけ方", s1: "dashboard.anannas.aiにアクセスしてログインします。", diff --git a/src/core/i18n/locales/ko.ts b/src/core/i18n/locales/ko.ts index ea8164e4f..9a46a9a63 100644 --- a/src/core/i18n/locales/ko.ts +++ b/src/core/i18n/locales/ko.ts @@ -7781,6 +7781,13 @@ export const koMessages: DeepPartialMessageTree = { s3: "없으면 새 키를 만드세요.", s4: "키를 복사하여 LettuceAI에 붙여넣으세요.", }, + modelrunner: { + title: "ModelRunner API 키를 찾는 방법", + s1: "modelrunner.ai를 방문하여 로그인하세요.", + s2: "Settings를 연 다음 API Keys로 이동하세요.", + s3: "없으면 새 키를 만드세요.", + s4: "키를 복사하여 LettuceAI에 붙여넣으세요.", + }, anannas: { title: "Anannas API 키를 찾는 방법", s1: "dashboard.anannas.ai로 이동하여 로그인하세요.", diff --git a/src/core/i18n/locales/nl.ts b/src/core/i18n/locales/nl.ts index 81b27e43d..0c33b1523 100644 --- a/src/core/i18n/locales/nl.ts +++ b/src/core/i18n/locales/nl.ts @@ -7781,6 +7781,13 @@ export const nlMessages: DeepPartialMessageTree = { s3: "Maak een nieuwe sleutel aan als je er geen ziet.", s4: "Kopieer de sleutel en plak hem in LettuceAI.", }, + modelrunner: { + title: "Hoe vind je je ModelRunner API-sleutel", + s1: "Bezoek modelrunner.ai en meld je aan.", + s2: "Open Settings en daarna API Keys.", + s3: "Maak een nieuwe sleutel aan als je er geen ziet.", + s4: "Kopieer de sleutel en plak hem in LettuceAI.", + }, anannas: { title: "Hoe vind je je Anannas API-sleutel", s1: "Ga naar dashboard.anannas.ai en log in.", diff --git a/src/core/i18n/locales/no.ts b/src/core/i18n/locales/no.ts index e59b8d60c..e785af063 100644 --- a/src/core/i18n/locales/no.ts +++ b/src/core/i18n/locales/no.ts @@ -7781,6 +7781,13 @@ export const noMessages: DeepPartialMessageTree = { s3: "Opprett en ny nøkkel hvis du ikke ser en.", s4: "Kopier nøkkelen og lim den inn i LettuceAI.", }, + modelrunner: { + title: "Slik finner du ModelRunner API-nøkkelen", + s1: "Besøk modelrunner.ai og logg inn.", + s2: "Åpne Settings og deretter API Keys.", + s3: "Opprett en ny nøkkel hvis du ikke ser en.", + s4: "Kopier nøkkelen og lim den inn i LettuceAI.", + }, anannas: { title: "Slik finner du Anannas API-nøkkelen", s1: "Gå til dashboard.anannas.ai og logg inn.", diff --git a/src/core/i18n/locales/pl.ts b/src/core/i18n/locales/pl.ts index 507305a5d..b08a14f5f 100644 --- a/src/core/i18n/locales/pl.ts +++ b/src/core/i18n/locales/pl.ts @@ -7054,6 +7054,13 @@ export const plMessages: DeepPartialMessageTree = { s3: "Utwórz nowy klucz jeśli go nie widzisz.", s4: "Skopiuj klucz i wklej go do LettuceAI.", }, + modelrunner: { + title: "Jak znaleźć klucz API ModelRunner", + s1: "Odwiedź modelrunner.ai i zaloguj się.", + s2: "Otwórz Settings, a następnie API Keys.", + s3: "Utwórz nowy klucz jeśli go nie widzisz.", + s4: "Skopiuj klucz i wklej go do LettuceAI.", + }, anannas: { title: "Jak znaleźć klucz API Anannas", s1: "Przejdź na dashboard.anannas.ai i zaloguj się.", diff --git a/src/core/i18n/locales/pt.ts b/src/core/i18n/locales/pt.ts index 15df3f406..52990f10e 100644 --- a/src/core/i18n/locales/pt.ts +++ b/src/core/i18n/locales/pt.ts @@ -6965,6 +6965,13 @@ export const ptMessages: DeepPartialMessageTree = { s3: "Create a new key if you do not see one.", s4: "Copy the key and paste it into LettuceAI.", }, + modelrunner: { + title: "Como encontrar a sua chave de API do ModelRunner", + s1: "Acesse modelrunner.ai e faça login.", + s2: "Abra Settings e depois API Keys.", + s3: "Crie uma nova chave se não vir nenhuma.", + s4: "Copie a chave e cole-a no LettuceAI.", + }, anannas: { title: "How to find your Anannas API key", s1: "Go to dashboard.anannas.ai and log in.", diff --git a/src/core/i18n/locales/ru.ts b/src/core/i18n/locales/ru.ts index bbe48c645..ff522bfc2 100644 --- a/src/core/i18n/locales/ru.ts +++ b/src/core/i18n/locales/ru.ts @@ -7781,6 +7781,13 @@ export const ruMessages: DeepPartialMessageTree = { s3: "Создайте новый ключ, если вы его не видите.", s4: "Скопируйте ключ и вставьте его в LettuceAI.", }, + modelrunner: { + title: "Как найти ключ API ModelRunner", + s1: "Посетите сайт modelrunner.ai и войдите в систему.", + s2: "Откройте Settings, затем API Keys.", + s3: "Создайте новый ключ, если вы его не видите.", + s4: "Скопируйте ключ и вставьте его в LettuceAI.", + }, anannas: { title: "Как найти ключ API Anannas", s1: "Перейдите на Dashboard.anannas.ai и войдите в систему.", diff --git a/src/core/i18n/locales/tr.ts b/src/core/i18n/locales/tr.ts index 42c3d577c..e0709c9e8 100644 --- a/src/core/i18n/locales/tr.ts +++ b/src/core/i18n/locales/tr.ts @@ -7781,6 +7781,13 @@ export const trMessages: DeepPartialMessageTree = { s3: "Görmüyorsanız yeni bir anahtar oluşturun.", s4: "Anahtarı kopyalayıp LettuceAI'ye yapıştırın.", }, + modelrunner: { + title: "ModelRunner API anahtarınızı nasıl bulursunuz", + s1: "modelrunner.ai adresini ziyaret edin ve oturum açın.", + s2: "Settings ve ardından API Keys bölümünü açın.", + s3: "Görmüyorsanız yeni bir anahtar oluşturun.", + s4: "Anahtarı kopyalayıp LettuceAI'ye yapıştırın.", + }, anannas: { title: "_Nasıl yapılır? ", s1: "Dashboard.anannas.ai adresine gidin ve giriş yapın.", diff --git a/src/core/i18n/locales/vi.ts b/src/core/i18n/locales/vi.ts index c0539e518..307b95d25 100644 --- a/src/core/i18n/locales/vi.ts +++ b/src/core/i18n/locales/vi.ts @@ -6965,6 +6965,13 @@ export const viMessages: DeepPartialMessageTree = { s3: "Create a new key if you do not see one.", s4: "Copy the key and paste it into LettuceAI.", }, + modelrunner: { + title: "Cách tìm khóa API ModelRunner của bạn", + s1: "Truy cập modelrunner.ai và đăng nhập.", + s2: "Mở Settings, rồi API Keys.", + s3: "Tạo khóa mới nếu bạn không thấy khóa nào.", + s4: "Sao chép khóa và dán vào LettuceAI.", + }, anannas: { title: "How to find your Anannas API key", s1: "Go to dashboard.anannas.ai and log in.", diff --git a/src/core/i18n/locales/zh-Hans.ts b/src/core/i18n/locales/zh-Hans.ts index 73035b32e..945a51290 100644 --- a/src/core/i18n/locales/zh-Hans.ts +++ b/src/core/i18n/locales/zh-Hans.ts @@ -7781,6 +7781,13 @@ export const zhHansMessages: DeepPartialMessageTree = { s3: "如未看到密钥请创建新密钥。", s4: "复制密钥并粘贴到 LettuceAI 中。", }, + modelrunner: { + title: "如何找到你的 ModelRunner API 密钥", + s1: "访问 modelrunner.ai 并登录。", + s2: "打开 Settings,然后进入 API Keys。", + s3: "如未看到密钥请创建新密钥。", + s4: "复制密钥并粘贴到 LettuceAI 中。", + }, anannas: { title: "如何找到你的 Anannas API 密钥", s1: "前往 dashboard.anannas.ai 并登录。", diff --git a/src/core/i18n/locales/zh-Hant.ts b/src/core/i18n/locales/zh-Hant.ts index 1d0d55bb0..4f989b126 100644 --- a/src/core/i18n/locales/zh-Hant.ts +++ b/src/core/i18n/locales/zh-Hant.ts @@ -7781,6 +7781,13 @@ export const zhHantMessages: DeepPartialMessageTree = { s3: "如果看不到金鑰,請建立新金鑰。", s4: "複製金鑰並貼入 LettuceAI。", }, + modelrunner: { + title: "如何找到您的 ModelRunner API 金鑰", + s1: "前往 modelrunner.ai 並登入。", + s2: "開啟 Settings,然後前往 API Keys。", + s3: "如果看不到金鑰,請建立新金鑰。", + s4: "複製金鑰並貼入 LettuceAI。", + }, anannas: { title: "如何找到您的 Anannas API 金鑰", s1: "前往 dashboard.anannas.ai 並登入。",