Bring-your-own keys for cloud providers (OpenAI-compatible)
Settings -> Providers takes keys for OpenAI, Anthropic (their official OpenAI-compatibility layer), DeepSeek, Groq, OpenRouter and any custom OpenAI-compatible endpoint. One adapter (lib/openai-compat) covers listing, streaming chat, JSON generation and vision, and every model flow can run on a provider: the chat picker lists each enabled provider's models (labelled, remembered), and a "Study generation" choice moves decks, homework, grading and attachment transcription onto a provider model. Keys stay in this browser exactly like the Ollama one (freezmo.providers.v1): never stored server-side, never in a backup or the sync payload, forwarded only with the request that needs them. The provider test asserts the key reaches the provider while the routing header stays on the app side. New suite tests/providers-test.mjs (13 checks) stubs both protocols: model listing, chat streaming, study generation and the Settings flow. Privacy policy updated (en+cs). Contrast 0 findings, axe clean, mobile 126/126, chat 102/102, wizard 95/95, bubbles 34/34, regression 44/44, i18n 13/13, native 33/33. Version 0.4.7, SW -> freezmo-v72.
This commit is contained in:
parent
37f7d22041
commit
4372423167
28 changed files with 1538 additions and 150 deletions
|
|
@ -739,6 +739,7 @@ const en: Record<string, string> = {
|
|||
/* server-side messages (API routes) -------------------------------- */
|
||||
"server.bodyNotJson": "Request body was not valid JSON.",
|
||||
"server.invalidRequest": "Invalid request: {detail}",
|
||||
"server.providerModelNeeded": "Pick the generation model in Settings → Providers.",
|
||||
"server.needContent": "Add at least one photo of your notes or paste some text to build a deck.",
|
||||
"server.needAssignment":
|
||||
"Add the assignment first — paste its text, photograph it, or add a document.",
|
||||
|
|
@ -1017,6 +1018,23 @@ const en: Record<string, string> = {
|
|||
"consent.ok": "Got it",
|
||||
"settings.version": "Version",
|
||||
"settings.chatNotes": "Keep notes text for chat",
|
||||
"providers.title": "Cloud providers",
|
||||
"providers.saveKey": "Save key",
|
||||
"providers.note": "Add your own API keys to use more models. Keys stay in this browser — the server forwards them with your requests and never stores them.",
|
||||
"providers.key": "API key",
|
||||
"providers.keySaved": "Key saved — paste a new one to replace",
|
||||
"providers.getKey": "Get a key",
|
||||
"providers.test": "Test and list models",
|
||||
"providers.remove": "Remove the key",
|
||||
"providers.testFailed": "Could not reach the provider. Check the key (and the base URL for custom endpoints).",
|
||||
"providers.modelCount": "{n} models",
|
||||
"providers.generation": "Study generation",
|
||||
"providers.generationNote": "Generate decks, homework and grading on a provider model instead of the server's Ollama.",
|
||||
"providers.serverDefault": "Server default (Ollama)",
|
||||
"providers.textModel": "Text model",
|
||||
"providers.visionModel": "Vision model",
|
||||
"providers.baseUrl": "OpenAI-compatible base URL",
|
||||
"providers.baseUrlPlaceholder": "https://host/v1",
|
||||
"settings.reduceMotion": "Reduce motion",
|
||||
"settings.reduceMotionNote": "Calms the scene and UI animations. Useful when motion feels distracting.",
|
||||
"settings.chatNotesNote": "Chat answers from the notes you added (stored with each deck). Turn off to use only the generated study content.",
|
||||
|
|
@ -1702,6 +1720,7 @@ const cs: Record<string, string> = {
|
|||
/* server-side messages (API routes) -------------------------------- */
|
||||
"server.bodyNotJson": "Tělo požadavku nebylo platné JSON.",
|
||||
"server.invalidRequest": "Neplatný požadavek: {detail}",
|
||||
"server.providerModelNeeded": "Vyberte model pro generování v Nastavení → Poskytovatelé.",
|
||||
"server.needContent": "Přidej aspoň jednu fotku poznámek nebo vlož text, ze kterého sada vznikne.",
|
||||
"server.needAssignment":
|
||||
"Nejdřív přidej zadání — vlož jeho text, vyfoť ho nebo přidej dokument.",
|
||||
|
|
@ -1980,6 +1999,23 @@ const cs: Record<string, string> = {
|
|||
"consent.ok": "Rozumím",
|
||||
"settings.version": "Verze",
|
||||
"settings.chatNotes": "Uchovávat text poznámek pro chat",
|
||||
"providers.title": "Cloudoví poskytovatelé",
|
||||
"providers.saveKey": "Uložit klíč",
|
||||
"providers.note": "Přidejte si vlastní API klíče a používejte více modelů. Klíče zůstávají v tomto prohlížeči — server je posílá jen s vašimi požadavky a nikdy je neukládá.",
|
||||
"providers.key": "API klíč",
|
||||
"providers.keySaved": "Klíč uložen — vložte nový pro nahrazení",
|
||||
"providers.getKey": "Získat klíč",
|
||||
"providers.test": "Otestovat a vypsat modely",
|
||||
"providers.remove": "Odstranit klíč",
|
||||
"providers.testFailed": "Nepodařilo se připojit k poskytovateli. Zkontrolujte klíč (a u vlastního endpointu i URL).",
|
||||
"providers.modelCount": "{n} modelů",
|
||||
"providers.generation": "Generování studia",
|
||||
"providers.generationNote": "Generovat sady, úkoly a hodnocení na modelu poskytovatele místo serverového Ollama.",
|
||||
"providers.serverDefault": "Serverové výchozí (Ollama)",
|
||||
"providers.textModel": "Textový model",
|
||||
"providers.visionModel": "Model pro obrázky",
|
||||
"providers.baseUrl": "OpenAI kompatibilní základní URL",
|
||||
"providers.baseUrlPlaceholder": "https://host/v1",
|
||||
"settings.reduceMotion": "Omezit pohyb",
|
||||
"settings.reduceMotionNote": "Zklidní scénu i animace rozhraní. Hodí se, když je pohyb rušivý.",
|
||||
"settings.chatNotesNote": "Chat odpovídá z poznámek, které jsi přidal (jsou uložené u každé sady). Vypnutím bude používat jen vygenerovaný obsah.",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue