diff --git a/bun.lockb b/bun.lockb index deaa93f5..8d4fe90e 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index c088aa46..84141a8d 100644 --- a/package.json +++ b/package.json @@ -62,7 +62,7 @@ }, "devDependencies": { "@plasmohq/prettier-plugin-sort-imports": "4.0.1", - "@types/chrome": "0.0.259", + "@types/chrome": "^0.0.280", "@types/d3-dsv": "^3.0.7", "@types/html-to-text": "^9.0.4", "@types/node": "20.11.9", diff --git a/src/assets/locale/da/settings.json b/src/assets/locale/da/settings.json index 372213f2..1666d9cd 100644 --- a/src/assets/locale/da/settings.json +++ b/src/assets/locale/da/settings.json @@ -30,7 +30,7 @@ "sendNotificationAfterIndexing": { "label": "Send besked efter færdigbehandling af vidensbasen" }, - "generateTitle" :{ + "generateTitle": { "label": "Generer titel med AI" } }, @@ -67,7 +67,6 @@ "label": "Slet Chathistorik", "button": "Slet", "confirm": "Er du sikker på, at du vil slette din chathistorik? Denne handling kan ikke fortrydes." - }, "export": { "label": "Eksporter chathistorik, vidensbase og prompts", @@ -162,7 +161,8 @@ "edit": "Ændre Prompt" }, "confirm": { - "delete": "Er du sikker på, at du vil slette denne prompt? Denne handling kan ikke fortrydes." }, + "delete": "Er du sikker på, at du vil slette denne prompt? Denne handling kan ikke fortrydes." + }, "modal": { "addTitle": "Tilføj ny Prompt", "editTitle": "Ændre Prompt" @@ -211,7 +211,8 @@ "label": "Page Deling URL", "placeholder": "Indtast websted deling URL", "required": "Venligst indstast din Page deling URL!", - "help": "Af hensyn til privatliv kan du selv hoste side delingen og angive URL'en her. Lær Mere." } + "help": "Af hensyn til privatliv kan du selv hoste side delingen og angive URL'en her. Lær Mere." + } }, "webshare": { "heading": "Web Deling", @@ -264,7 +265,8 @@ "placeholder": "Bearer token" } }, - "help": "Hvis du har forbindelsesproblemer med Ollama på Page Assist, kan du konfigurere en brugerdefineret oprindelses-URL. For mere information om konfigurationen, klik her." } + "help": "Hvis du har forbindelsesproblemer med Ollama på Page Assist, kan du konfigurere en brugerdefineret oprindelses-URL. For mere information om konfigurationen, klik her." + } } }, "manageSearch": { diff --git a/src/assets/locale/de/settings.json b/src/assets/locale/de/settings.json index d44390ad..30a5da3b 100644 --- a/src/assets/locale/de/settings.json +++ b/src/assets/locale/de/settings.json @@ -30,7 +30,7 @@ "sendNotificationAfterIndexing": { "label": "Benachrichtigung nach Abschluss der Wissensbasis-Verarbeitung senden" }, - "generateTitle" :{ + "generateTitle": { "label": "Titel mit KI generieren" } }, diff --git a/src/assets/locale/en/common.json b/src/assets/locale/en/common.json index 0cd96d7b..f5b9e398 100644 --- a/src/assets/locale/en/common.json +++ b/src/assets/locale/en/common.json @@ -117,4 +117,4 @@ }, "pin": "Pin", "unpin": "Unpin" -} \ No newline at end of file +} diff --git a/src/assets/locale/en/settings.json b/src/assets/locale/en/settings.json index eb54db86..8f19b6a9 100644 --- a/src/assets/locale/en/settings.json +++ b/src/assets/locale/en/settings.json @@ -30,7 +30,7 @@ "sendNotificationAfterIndexing": { "label": "Send Notification After Finishing Processing the Knowledge Base" }, - "generateTitle" :{ + "generateTitle": { "label": "Generate Title using AI" } }, diff --git a/src/assets/locale/no/settings.json b/src/assets/locale/no/settings.json index fb90aa5f..a09437fa 100644 --- a/src/assets/locale/no/settings.json +++ b/src/assets/locale/no/settings.json @@ -30,7 +30,7 @@ "sendNotificationAfterIndexing": { "label": "Send varsel etter ferdigbehandling av kunnskapsbasen" }, - "generateTitle" :{ + "generateTitle": { "label": "Generer tittel med AI" } }, diff --git a/src/assets/locale/sv/chrome.json b/src/assets/locale/sv/chrome.json new file mode 100644 index 00000000..bb016505 --- /dev/null +++ b/src/assets/locale/sv/chrome.json @@ -0,0 +1,13 @@ +{ + "heading": "Konfigurera Chrome AI", + "status": { + "label": "Aktivera eller inaktivera Chrome AI-stöd på Page Assist" + }, + "error": { + "browser_not_supported": "Denna version av Chrome stöds inte av Gemini Nano-modellen. Uppdatera till version 127 eller senare", + "ai_not_supported": "Inställningen chrome://flags/#prompt-api-for-gemini-nano är inte aktiverad. Var vänlig och aktivera den.", + "ai_not_ready": "Gemini Nano är inte redo än; du måste dubbelkolla Chrome-inställningarna.", + "internal_error": "Ett internt fel uppstod. Försök igen senare." + }, + "errorDescription": "För att använda Chrome AI, behöver du en webbläsarversion högre än 127, som för närvarande finns i Dev- och Canary-kanalerna. Efter att ha laddat ner den stödda versionen, följ dessa steg:\n\n1. Gå till `chrome://flags/#prompt-api-for-gemini-nano` och välj \"Enable\".\n2. Gå till `chrome://flags/#optimization-guide-on-device-model` och välj \"EnabledBypassPrefRequirement\".\n3. Gå till `chrome://components`, sök efter \"Optimization Guide On Device Model\" och klicka på \"Check for Update\". Detta kommer att ladda ner modellen. Om du inte ser inställningarna, upprepa steg 1 och 2 och starta om webbläsaren." +} diff --git a/src/assets/locale/sv/common.json b/src/assets/locale/sv/common.json new file mode 100644 index 00000000..31272676 --- /dev/null +++ b/src/assets/locale/sv/common.json @@ -0,0 +1,120 @@ +{ + "pageAssist": "Page Assist", + "selectAModel": "Välj en modell", + "save": "Spara", + "saved": "Sparad", + "cancel": "Avbryt", + "retry": "Försök igen", + "share": { + "tooltip": { + "share": "Dela" + }, + "modal": { + "title": "Dela länk till chatt" + }, + "form": { + "defaultValue": { + "name": "Anonym", + "title": "Chatt utan titel" + }, + "title": { + "label": "Chattitel", + "placeholder": "Ange chattitel", + "required": "Chattitel krävs" + }, + "name": { + "label": "Ditt namn", + "placeholder": "Ange ditt namn", + "required": "Ditt namn krävs" + }, + "btn": { + "save": "Generera länk", + "saving": "Genererar länk..." + } + }, + "notification": { + "successGenerate": "Länk kopierad till urklipp", + "failGenerate": "Misslyckades med att generera länk" + } + }, + "copyToClipboard": "Kopiera till urklipp", + "webSearch": "Söker på webben", + "regenerate": "Återskapa", + "edit": "Redigera", + "delete": "Radera", + "saveAndSubmit": "Spara & Skicka", + "editMessage": { + "placeholder": "Skriv ett meddelande..." + }, + "submit": "Skicka", + "noData": "Inga data", + "noHistory": "Ingen chattlogg", + "chatWithCurrentPage": "Chatta med nuvarande sidan", + "beta": "Beta", + "tts": "Läs högt", + "currentChatModelSettings": "Nuvarande chattmodellinställningar", + "modelSettings": { + "label": "Modellinställningar", + "description": "Ställ in modellalternativen globalt för alla chatter", + "form": { + "keepAlive": { + "label": "Keep Alive", + "help": "kontrollerar hur länge modellen kommer att vara laddad i minnet efter förfrågan (standard: 5 min)", + "placeholder": "Ange Keep Alive varaktighet (t.ex. 5m, 10m, 1h)" + }, + "temperature": { + "label": "Temperatur", + "placeholder": "Ange temperaturvärde (t.ex. 0.7, 1.0)" + }, + "numCtx": { + "label": "Antal kontexter", + "placeholder": "Ange antal kontextvärden (standard: 2048)" + }, + "seed": { + "label": "Frö", + "placeholder": "Ange frövärde (t.ex. 1234)", + "help": "Reproducerbarhet av modellens utskrift" + }, + "topK": { + "label": "Topp K", + "placeholder": "Ange Topp K värde (t.ex. 40, 100)" + }, + "topP": { + "label": "Topp P", + "placeholder": "Ange Topp P värde (t.ex. 0.9, 0.95)" + }, + "numGpu": { + "label": "Antal GPU", + "placeholder": "Ange antal lager att skicka till GPU(s)" + }, + "systemPrompt": { + "label": "Tillfällig systempromt", + "placeholder": "Ange systemprompt", + "help": "Detta är ett snabbt sätt att ställa in systemprompten i den nuvarande chatten, vilket kommer att åsidosätta den valda systemprompten om den finns." + } + }, + "advanced": "Fler modellinställningar" + }, + "copilot": { + "summary": "Sammanfatta", + "explain": "Förklara", + "rephrase": "Formulera om", + "translate": "Översätt", + "custom": "Custom" + }, + "citations": "Citat", + "segmented": { + "ollama": "Ollama-modeller", + "custom": "Custom modeller" + }, + "downloadCode": "Ladda ner kod", + "date": { + "pinned": "Fäst", + "today": "Idag", + "yesterday": "Igår", + "last7Days": "Senaste 7 dagarna", + "older": "Äldre" + }, + "pin": "Fäst", + "unpin": "Ta bort fäst" +} diff --git a/src/assets/locale/sv/knowledge.json b/src/assets/locale/sv/knowledge.json new file mode 100644 index 00000000..a01b1a2e --- /dev/null +++ b/src/assets/locale/sv/knowledge.json @@ -0,0 +1,40 @@ +{ + "addBtn": "Lägg till ny kunskap", + "columns": { + "title": "Titel", + "status": "Status", + "embeddings": "Inbäddningsmodell", + "createdAt": "Skapad den", + "action": "Åtgärder" + }, + "expandedColumns": { + "name": "Namn" + }, + "confirm": { + "delete": "Är du säker på att du vill ta bort denna kunskap?" + }, + "deleteSuccess": "Kunskap raderades framgångsrikt", + "status": { + "pending": "Väntar", + "finished": "Klar", + "processing": "Bearbetar", + "failed": "Misslyckades" + }, + "addKnowledge": "Lägg till kunskap", + "form": { + "title": { + "label": "Kunskapstitel", + "placeholder": "Ange kunskapstitel", + "required": "Kunskapstitel är obligatorisk" + }, + "uploadFile": { + "label": "Ladda upp fil", + "uploadText": "Dra och släpp en fil här eller klicka för att ladda upp", + "uploadHint": "Stödda filtyper: .pdf, .csv, .txt, .md, .docx", + "required": "Fil är obligatorisk" + }, + "submit": "Skicka in", + "success": "Kunskap tillagd framgångsrikt" + }, + "noEmbeddingModel": "Vänligen lägg till en inbäddningsmodell från sidan för RAG-inställningar först" +} diff --git a/src/assets/locale/sv/openai.json b/src/assets/locale/sv/openai.json new file mode 100644 index 00000000..55bdbc71 --- /dev/null +++ b/src/assets/locale/sv/openai.json @@ -0,0 +1,90 @@ +{ + "settings": "OpenAI-kompatibel API", + "heading": "OpenAI-kompatibel API", + "subheading": "Hantera och konfigurera dina OpenAI API-kompatibla leverantörer här.", + "addBtn": "Lägg till leverantör", + "table": { + "name": "Leverantörsnamn", + "baseUrl": "Bas-URL", + "actions": "Åtgärd" + }, + "modal": { + "titleAdd": "Lägg till ny leverantör", + "name": { + "label": "Leverantörsnamn", + "required": "Leverantörsnamn krävs.", + "placeholder": "Ange leverantörsnamn" + }, + "baseUrl": { + "label": "Bas-URL", + "help": "Bas-URL för OpenAI API-leverantören. t.ex. (http://localhost:1234/v1)", + "required": "Bas-URL krävs.", + "placeholder": "Ange bas-URL" + }, + "apiKey": { + "label": "API-nyckel", + "required": "API-nyckel krävs.", + "placeholder": "Ange API-nyckel" + }, + "submit": "Spara", + "update": "Uppdatera", + "deleteConfirm": "Är du säker på att du vill radera denna leverantör?", + "model": { + "title": "Modellista", + "subheading": "Vänligen välj chattmodellerna du vill använda med denna leverantör.", + "success": "Nya modeller har lagts till framgångsrikt." + }, + "tipLMStudio": "Page Assist hämtar automatiskt modellerna du laddat i LM Studio. Ingen manuell tilläggning behövs." + }, + "addSuccess": "Leverantör tillagd framgångsrikt.", + "deleteSuccess": "Leverantör raderad framgångsrikt.", + "updateSuccess": "Leverantör uppdaterad framgångsrikt.", + "delete": "Radera", + "edit": "Redigera", + "newModel": "Lägg till modeller till leverantör", + "noNewModel": "För LMStudio hämtar vi dynamiskt. Ingen manuell tilläggning behövs.", + "searchModel": "Sök modell", + "selectAll": "Välj alla", + "save": "Spara", + "saving": "Sparar...", + "manageModels": { + "columns": { + "name": "Modellnamn", + "model_type": "Modelltyp", + "model_id": "Modell-ID", + "provider": "Leverantörsnamn", + "actions": "Åtgärd" + }, + "tooltip": { + "delete": "Radera" + }, + "confirm": { + "delete": "Är du säker på att du vill radera denna modell?" + }, + "modal": { + "title": "Lägg till Custom-modell", + "form": { + "name": { + "label": "Modell-ID", + "placeholder": "llama3.2", + "required": "Modell-ID krävs." + }, + "provider": { + "label": "Leverantör", + "placeholder": "Välj leverantör", + "required": "Leverantör krävs." + }, + "type": { + "label": "Modelltyp" + } + } + } + }, + "noModelFound": "Ingen modell hittades. Se till att du har lagt till korrekt leverantör med bas-URL och API-nyckel.", + "radio": { + "chat": "Chattmodell", + "embedding": "Inbäddningsmodell", + "chatInfo": "används för chattkompletion och konversationsgenerering", + "embeddingInfo": "används för RAG och andra semantiska sökrelaterade uppgifter." + } +} diff --git a/src/assets/locale/sv/option.json b/src/assets/locale/sv/option.json new file mode 100644 index 00000000..d7017eec --- /dev/null +++ b/src/assets/locale/sv/option.json @@ -0,0 +1,12 @@ +{ + "newChat": "Ny chatt", + "selectAPrompt": "Välj en fråga", + "githubRepository": "GitHu repository", + "settings": "Inställningar", + "sidebarTitle": "Chatthistorik", + "error": "Fel", + "somethingWentWrong": "Något gick fel", + "validationSelectModel": "Vänligen välj en modell för att fortsätta", + "deleteHistoryConfirmation": "Är du säker på att du vill radera denna historik?", + "editHistoryTitle": "Ange en ny titel" +} diff --git a/src/assets/locale/sv/playground.json b/src/assets/locale/sv/playground.json new file mode 100644 index 00000000..d7195c56 --- /dev/null +++ b/src/assets/locale/sv/playground.json @@ -0,0 +1,29 @@ +{ + "ollamaState": { + "searching": "Söker efter din Ollama 🦙", + "running": "Ollama körs 🦙", + "notRunning": "Kan inte ansluta till Ollama 🦙", + "connectionError": "Det verkar som att du har ett anslutningsfel. Vänligen se denna dokumentation för felsökning." + }, + "formError": { + "noModel": "Vänligen välj en modell", + "noEmbeddingModel": "Vänligen ställ in en inbäddningsmodell på sidan Inställningar > RAG" + }, + "form": { + "textarea": { + "placeholder": "Skriv ett meddelande..." + }, + "webSearch": { + "on": "På", + "off": "Av" + } + }, + "tooltip": { + "searchInternet": "Sök på Internet", + "speechToText": "Tal till text", + "uploadImage": "Ladda upp bild", + "stopStreaming": "Stoppa strömning", + "knowledge": "Kunskap" + }, + "sendWhenEnter": "Skicka när Enter trycks" +} diff --git a/src/assets/locale/sv/settings.json b/src/assets/locale/sv/settings.json new file mode 100644 index 00000000..cb28f1ef --- /dev/null +++ b/src/assets/locale/sv/settings.json @@ -0,0 +1,341 @@ +{ + "generalSettings": { + "title": "Allmänna Inställningar", + "settings": { + "heading": "Webbgränssnitt Inställningar", + "speechRecognitionLang": { + "label": "Taligenkänningsspråk", + "placeholder": "Välj ett språk" + }, + "language": { + "label": "Språk", + "placeholder": "Välj ett språk" + }, + "darkMode": { + "label": "Byt Tema", + "options": { + "light": "Ljust", + "dark": "Mörkt" + } + }, + "copilotResumeLastChat": { + "label": "Återuppta den senaste chatten när du öppnar sidopanelen (Copilot)" + }, + "hideCurrentChatModelSettings": { + "label": "Göm de nuvarande chattmodellinställningarna" + }, + "restoreLastChatModel": { + "label": "Återställ den senast använda modellen för tidigare chatter" + }, + "sendNotificationAfterIndexing": { + "label": "Skicka meddelande efter att ha avslutat bearbetning av kunskapsbasen" + }, + "generateTitle": { + "label": "Generera titel med AI" + } + }, + "sidepanelRag": { + "heading": "Copilot Chatt med Webbplats Inställningar", + "ragEnabled": { + "label": "Chatta med webbplatsen med vektorinbäddningar" + }, + "maxWebsiteContext": { + "label": "Vanligt läge webbplatsinnehållsstorlek", + "placeholder": "Innehållsstorlek (standard 4028)" + } + }, + "webSearch": { + "heading": "Hantera Webb Sök", + "searchMode": { + "label": "Utför Enkel InternetSökning" + }, + "provider": { + "label": "Sökmotor", + "placeholder": "Välj en sökmotor" + }, + "totalSearchResults": { + "label": "Totalt Sökresultat", + "placeholder": "Ange Totalt Sökresultat" + }, + "visitSpecificWebsite": { + "label": "Besök webbplatsen som nämns i meddelandet" + } + }, + "system": { + "heading": "Systeminställningar", + "deleteChatHistory": { + "label": "Radera Chatt Historik", + "button": "Radera", + "confirm": "Är du säker på att du vill radera din chatthistorik? Denna åtgärd kan inte ångras." + }, + "export": { + "label": "Exportera chatthistorik, kunskapsbas och instruktioner", + "button": "Exportera Data", + "success": "Exportering Lyckades" + }, + "import": { + "label": "Importera chatthistorik, kunskapsbas och instruktioner", + "button": "Importera Data", + "success": "Importering Lyckades", + "error": "Importeringsfel" + } + }, + "tts": { + "heading": "Text till Tal Inställningar", + "ttsEnabled": { + "label": "Aktivera Text till Tal" + }, + "ttsProvider": { + "label": "Text till Tal Leverantör", + "placeholder": "Välj en leverantör" + }, + "ttsVoice": { + "label": "Text till Tal Röst", + "placeholder": "Välj en röst" + }, + "ssmlEnabled": { + "label": "Aktivera SSML (Speech Synthesis Markup Language)" + } + } + }, + "manageModels": { + "title": "Hantera Modeller", + "addBtn": "Lägg till Ny Modell", + "columns": { + "name": "Namn", + "digest": "Sammanfattning", + "modifiedAt": "Modifierad Den", + "size": "Storlek", + "actions": "Åtgärder" + }, + "expandedColumns": { + "parentModel": "Föräldramodell", + "format": "Format", + "family": "Familj", + "parameterSize": "Parameterstorlek", + "quantizationLevel": "Kvantifieringsnivå" + }, + "tooltip": { + "delete": "Radera Modell", + "repull": "Hämta Modell Igen" + }, + "confirm": { + "delete": "Är du säker på att du vill radera denna modell?", + "repull": "Är du säker på att du vill hämta modellen igen?" + }, + "modal": { + "title": "Lägg till Ny Modell", + "placeholder": "Ange Modellnamn", + "pull": "Hämta Modell" + }, + "notification": { + "pullModel": "Hämtar Modell", + "pullModelDescription": "Hämtar {{modelName}} modell. För mer information, kontrollera ikonen för tillägget.", + "success": "Lyckades", + "error": "Fel", + "successDescription": "Modellen hämtades framgångsrikt", + "successDeleteDescription": "Modellen raderades framgångsrikt", + "someError": "Något gick fel. Försök igen senare" + } + }, + "managePrompts": { + "title": "Hantera instruktioner", + "addBtn": "Lägg till ny instruktion", + "option1": "Normal", + "option2": "RAG", + "questionPrompt": "Frågeinstruktion", + "segmented": { + "custom": "Custom instruktion", + "copilot": "Copilot instruktion" + }, + "columns": { + "title": "Titel", + "prompt": "instruktion", + "type": "Instruktionstyp", + "actions": "Åtgärder" + }, + "systemPrompt": "Systeminstruktion", + "quickPrompt": "Snabb instruktion", + "tooltip": { + "delete": "Radera instruktion", + "edit": "Redigera instruktion" + }, + "confirm": { + "delete": "Är du säker på att du vill radera denna instruktion? Denna åtgärd kan inte ångras." + }, + "modal": { + "addTitle": "Lägg till ny instruktion", + "editTitle": "Redigera instruktion" + }, + "form": { + "title": { + "label": "Titel", + "placeholder": "Min fantastiska instruktion", + "required": "Vänligen ange en titel" + }, + "prompt": { + "label": "Instruktion", + "placeholder": "Ange instruktion", + "required": "Vänligen ange en instruktion", + "help": "Du kan använda {key} som variabel i din instruktion.", + "missingTextPlaceholder": "Variabeln {text} saknas i instruktionen. Lägg till den." + }, + "isSystem": { + "label": "Är Systeminstruktion" + }, + "btnSave": { + "saving": "Lägger till instruktion...", + "save": "Lägg till instruktion" + }, + "btnEdit": { + "saving": "Uppdaterar instruktion...", + "save": "Uppdatera instruktion" + } + }, + "notification": { + "addSuccess": "Instruktion Tillagd", + "addSuccessDesc": "Instruktionen har lagts till framgångsrikt", + "error": "Fel", + "someError": "Något gick fel. Försök igen senare", + "updatedSuccess": "Instruktion Uppdaterad", + "updatedSuccessDesc": "Instruktionen har uppdaterats framgångsrikt", + "deletedSuccess": "Instruktion Raderad", + "deletedSuccessDesc": "Instruktionen har raderats framgångsrikt" + } + }, + "manageShare": { + "title": "Hantera Delningar", + "heading": "Konfigurera Sidans Delnings-URL", + "form": { + "url": { + "label": "Sidans Delnings-URL", + "placeholder": "Ange Sidans Delnings-URL", + "required": "Vänligen ange din Sidans Delnings-URL!", + "help": "För integritetsskäl, kan du använda egen värd för sidans delning och ange URL här. Läs Mer." + } + }, + "webshare": { + "heading": "Webbdelning", + "columns": { + "title": "Titel", + "url": "URL", + "actions": "Åtgärder" + }, + "tooltip": { + "delete": "Radera Delning" + }, + "confirm": { + "delete": "Är du säker på att du vill radera denna delning? Denna åtgärd kan inte ångras." + }, + "label": "Hantera Sidans Delning", + "description": "Aktivera eller inaktivera funktionen för sidans delning" + }, + "notification": { + "pageShareSuccess": "Sidans Delnings-URL uppdaterad framgångsrikt", + "someError": "Något gick fel. Försök igen senare", + "webShareDeleteSuccess": "Webbdelning raderades framgångsrikt" + } + }, + "ollamaSettings": { + "title": "Ollamainställningar", + "heading": "Konfigurera Ollama", + "settings": { + "ollamaUrl": { + "label": "Ollama URL", + "placeholder": "Ange Ollama URL" + }, + "advanced": { + "label": "Avancerad Ollama URL-konfiguration", + "urlRewriteEnabled": { + "label": "Aktivera eller inaktivera custom ursprungs-URL" + }, + "rewriteUrl": { + "label": "Custom ursprungs-URL", + "placeholder": "Ange Custom ursprungs-URL" + }, + "headers": { + "label": "Custom Headers", + "add": "Lägg till Header", + "key": { + "label": "Headernyckel", + "placeholder": "Auktorisering" + }, + "value": { + "label": "Headervärde", + "placeholder": "Bärare token" + } + }, + "help": "Om du har anslutningsproblem med Ollama på Page Assist, kan du konfigurera en custom ursprungs-URL. För att veta mer om konfigurationen, klicka här." + } + } + }, + "manageSearch": { + "title": "Hantera Webbsök", + "heading": "Konfigurera Webbsök" + }, + "about": { + "title": "Om", + "heading": "Om", + "chromeVersion": "Page Assist Version", + "ollamaVersion": "Ollamaversion", + "support": "Du kan stödja Page Assist-projektet genom att donera eller sponsra genom följande plattformar:", + "koFi": "Stöd på Ko-fi", + "githubSponsor": "Sponsra på GitHub", + "githubRepo": "GitHub repository" + }, + "manageKnowledge": { + "title": "Hantera kunskap", + "heading": "Konfigurera kunskapsbas" + }, + "rag": { + "title": "RAG-inställningar", + "ragSettings": { + "label": "RAG-inställningar", + "model": { + "label": "Inbäddningsmodell", + "required": "Vänligen välj en modell", + "help": "Det rekommenderas starkt att använda inbäddningsmodeller som 'nomic-embed-text'.", + "placeholder": "Välj en modell" + }, + "chunkSize": { + "label": "Chunkstorlek", + "placeholder": "Ange chunkstorlek", + "required": "Vänligen ange en chunkstorlek" + }, + "chunkOverlap": { + "label": "Chunköverlapp", + "placeholder": "Ange chunköverlapp", + "required": "Vänligen ange en chunköverlapp" + }, + "totalFilePerKB": { + "label": "Standardgräns för kunskapsbas filuppladdning", + "placeholder": "Ange standardgräns för filuppladdning (t.ex. 10)", + "required": "Vänligen ange standardgräns för filuppladdning" + }, + "noOfRetrievedDocs": { + "label": "Antal hämtade dokument", + "placeholder": "Ange antal hämtade dokument", + "required": "Vänligen ange antal hämtade dokument" + } + }, + "prompt": { + "label": "Konfigurera RAG-instruktion", + "option1": "Normal", + "option2": "Webb", + "alert": "Att konfigurera systeminstruktionen här är föråldrat. Använd Hantera instruktioner-sektionen för att lägga till eller redigera instruktionar. Denna sektion kommer att tas bort i en framtida version", + "systemPrompt": "Systeminstruktion", + "systemPromptPlaceholder": "Ange systeminstruktion", + "webSearchPrompt": "Webbsökinstruktion", + "webSearchPromptHelp": "Ta inte bort '{search_results}' från instruktionen.", + "webSearchPromptError": "Vänligen ange en instruktion för webbsökning", + "webSearchPromptPlaceholder": "Ange instruktion för webbsök", + "webSearchFollowUpPrompt": "Uppföljningsinstruktion för webbsök", + "webSearchFollowUpPromptHelp": "Ta inte bort '{chat_history}' och '{question}' från instruktionen.", + "webSearchFollowUpPromptError": "Vänligen ange din uppföljningsinstruktion för webbsök!", + "webSearchFollowUpPromptPlaceholder": "Din uppföljningsinstruktion för webbsök" + } + }, + "chromeAiSettings": { + "title": "Chrome AI-inställningar" + } +} diff --git a/src/assets/locale/sv/sidepanel.json b/src/assets/locale/sv/sidepanel.json new file mode 100644 index 00000000..5c8672a7 --- /dev/null +++ b/src/assets/locale/sv/sidepanel.json @@ -0,0 +1,7 @@ +{ + "tooltip": { + "embed": "Det kan ta några minuter att bädda in sidan. Vänta...", + "clear": "Radera chatthistorik", + "history": "Chatthistorik" + } +} diff --git a/src/components/Common/Markdown.tsx b/src/components/Common/Markdown.tsx index 2934b640..c996acf1 100644 --- a/src/components/Common/Markdown.tsx +++ b/src/components/Common/Markdown.tsx @@ -8,20 +8,8 @@ import rehypeKatex from "rehype-katex" import "property-information" import React from "react" import { CodeBlock } from "./CodeBlock" -export const preprocessLaTeX = (content: string) => { - // Replace block-level LaTeX delimiters \[ \] with $$ $$ +import { preprocessLaTeX } from "@/utils/latex" - const blockProcessedContent = content.replace( - /\\\[(.*?)\\\]/gs, - (_, equation) => `$$${equation}$$` - ) - // Replace inline LaTeX delimiters \( \) with $ $ - const inlineProcessedContent = blockProcessedContent.replace( - /\\\((.*?)\\\)/gs, - (_, equation) => `$${equation}$` - ) - return inlineProcessedContent -} function Markdown({ message, className = "prose break-words dark:prose-invert prose-p:leading-relaxed prose-pre:p-0 dark:prose-dark" diff --git a/src/components/Common/Playground/EditMessageForm.tsx b/src/components/Common/Playground/EditMessageForm.tsx index e818f24f..f42b6d41 100644 --- a/src/components/Common/Playground/EditMessageForm.tsx +++ b/src/components/Common/Playground/EditMessageForm.tsx @@ -5,7 +5,7 @@ import useDynamicTextareaSize from "~/hooks/useDynamicTextareaSize" type Props = { value: string - onSumbit: (value: string) => void + onSumbit: (value: string, isSend: boolean) => void onClose: () => void isBot: boolean } @@ -31,7 +31,7 @@ export const EditMessageForm = (props: Props) => { onSubmit={form.onSubmit((data) => { if (isComposing) return props.onClose() - props.onSumbit(data.message) + props.onSumbit(data.message, true) })} className="flex flex-col gap-2"> { ref={textareaRef} className="w-full bg-transparent focus-within:outline-none focus:ring-0 focus-visible:ring-0 ring-0 dark:ring-0 border-0 dark:text-gray-100" /> - - - {props.isBot ? t("save") : t("saveAndSubmit")} - - - {t("cancel")} - - + + + {!props.isBot && ( + { + props.onSumbit(form.values.message, false) + props.onClose() + }} + aria-label={t("save")} + className="border border-gray-600 px-2 py-1.5 rounded-lg text-gray-700 dark:text-gray-300 focus:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:ring-gray-500 hover:bg-gray-100 dark:hover:bg-gray-900 text-sm"> + {t("save")} + + )} + + + {props.isBot ? t("save") : t("saveAndSubmit")} + + + + {t("cancel")} + + + + {" "} ) } diff --git a/src/components/Common/Playground/Message.tsx b/src/components/Common/Playground/Message.tsx index 9d664a11..0c6299c6 100644 --- a/src/components/Common/Playground/Message.tsx +++ b/src/components/Common/Playground/Message.tsx @@ -29,7 +29,7 @@ type Props = { currentMessageIndex: number totalMessages: number onRengerate: () => void - onEditFormSubmit: (value: string) => void + onEditFormSubmit: (value: string, isSend: boolean) => void isProcessing: boolean webSearch?: {} isSearchingInternet?: boolean diff --git a/src/components/Option/Playground/PlaygroundChat.tsx b/src/components/Option/Playground/PlaygroundChat.tsx index 4a2795be..5f2adfe2 100644 --- a/src/components/Option/Playground/PlaygroundChat.tsx +++ b/src/components/Option/Playground/PlaygroundChat.tsx @@ -46,8 +46,8 @@ export const PlaygroundChat = () => { isProcessing={streaming} isSearchingInternet={isSearchingInternet} sources={message.sources} - onEditFormSubmit={(value) => { - editMessage(index, value, !message.isBot) + onEditFormSubmit={(value, isSend) => { + editMessage(index, value, !message.isBot, isSend) }} onSourceClick={(data) => { setSource(data) diff --git a/src/components/Option/Settings/tts-mode.tsx b/src/components/Option/Settings/tts-mode.tsx index a85316b4..7360419d 100644 --- a/src/components/Option/Settings/tts-mode.tsx +++ b/src/components/Option/Settings/tts-mode.tsx @@ -86,11 +86,10 @@ export const TTSModeSettings = ({ hideBorder }: { hideBorder?: boolean }) => { placeholder={t("generalSettings.tts.ttsVoice.placeholder")} className="w-full mt-4 sm:mt-0 sm:w-[200px]" options={data?.browserTTSVoices?.map( - (voice) => - ({ - label: `${voice.voiceName} - ${voice.lang}`.trim(), - value: voice.voiceName - }) || [] + (voice) => ({ + label: `${voice.voiceName} - ${voice.lang}`.trim(), + value: voice.voiceName + }) )} {...form.getInputProps("voice")} /> diff --git a/src/entries/hf-pull.content.ts b/src/entries/hf-pull.content.ts index 94066831..ac447376 100644 --- a/src/entries/hf-pull.content.ts +++ b/src/entries/hf-pull.content.ts @@ -66,10 +66,12 @@ export default defineContentScript({ ) } }) - copyButton.parentElement!.insertBefore( - downloadButton, - copyButton.nextSibling - ) + const buttonContainer = document.createElement('div') + buttonContainer.classList.add("mb-3") + buttonContainer.style.display = 'flex' + buttonContainer.style.justifyContent = 'flex-end' + buttonContainer.appendChild(downloadButton) + modal.querySelector("pre")!.insertAdjacentElement("afterend", buttonContainer) } } diff --git a/src/hooks/useMessageOption.tsx b/src/hooks/useMessageOption.tsx index c7a2edb3..58d56bfc 100644 --- a/src/hooks/useMessageOption.tsx +++ b/src/hooks/useMessageOption.tsx @@ -910,12 +910,14 @@ export const useMessageOption = () => { const editMessage = async ( index: number, message: string, - isHuman: boolean + isHuman: boolean, + isSend: boolean ) => { let newMessages = messages let newHistory = history - if (isHuman) { + // if human message and send then only trigger the submit + if (isHuman && isSend) { const isOk = validateBeforeSubmit() if (!isOk) { @@ -939,13 +941,13 @@ export const useMessageOption = () => { memory: previousHistory, controller: abortController }) - } else { - newMessages[index].message = message - setMessages(newMessages) - newHistory[index].content = message - setHistory(newHistory) - await updateMessageByIndex(historyId, index, message) + return } + newMessages[index].message = message + setMessages(newMessages) + newHistory[index].content = message + setHistory(newHistory) + await updateMessageByIndex(historyId, index, message) } return { diff --git a/src/i18n/index.ts b/src/i18n/index.ts index 0b495719..97bbf6f8 100644 --- a/src/i18n/index.ts +++ b/src/i18n/index.ts @@ -13,6 +13,7 @@ import { fa } from "./lang/fa"; import { de } from "./lang/de"; import { da } from "./lang/da"; import { no } from "./lang/no"; +import { sv } from "./lang/sv"; i18n @@ -35,7 +36,8 @@ i18n "fa-IR": fa, da: da, no: no, - de: de + de: de, + sv: sv }, fallbackLng: "en", lng: localStorage.getItem("i18nextLng") || "en", diff --git a/src/i18n/lang/sv.ts b/src/i18n/lang/sv.ts new file mode 100644 index 00000000..39938b86 --- /dev/null +++ b/src/i18n/lang/sv.ts @@ -0,0 +1,19 @@ +import option from "@/assets/locale/sv/option.json"; +import playground from "@/assets/locale/sv/playground.json"; +import common from "@/assets/locale/sv/common.json"; +import sidepanel from "@/assets/locale/sv/sidepanel.json"; +import settings from "@/assets/locale/sv/settings.json"; +import knowledge from "@/assets/locale/sv/knowledge.json"; +import chrome from "@/assets/locale/sv/chrome.json"; +import openai from "@/assets/locale/sv/openai.json"; + +export const sv = { + option, + playground, + common, + sidepanel, + settings, + knowledge, + chrome, + openai +} diff --git a/src/i18n/support-language.ts b/src/i18n/support-language.ts index c9bbfa18..2c62ad40 100644 --- a/src/i18n/support-language.ts +++ b/src/i18n/support-language.ts @@ -51,5 +51,9 @@ export const supportLanguage = [ { label: "Norsk", value: "no" + }, + { + value: "sv", + label: "Svenska" } ] diff --git a/src/libs/get-html.ts b/src/libs/get-html.ts index ddb2ad7a..29bbd9e7 100644 --- a/src/libs/get-html.ts +++ b/src/libs/get-html.ts @@ -42,14 +42,30 @@ export const getDataFromCurrentTab = async () => { .query({ active: true, currentWindow: true }) .then(async (tabs) => { const tab = tabs[0] + try { + const data = await browser.scripting.executeScript({ + target: { tabId: tab.id }, + func: _getHtml + }) - const data = await browser.scripting.executeScript({ - target: { tabId: tab.id }, - func: _getHtml - }) - - if (data.length > 0) { - resolve(data[0].result) + if (data.length > 0) { + resolve(data[0].result) + } + } catch (e) { + console.log("error", e) + // this is a weird method but it works + if (import.meta.env.BROWSER === "firefox") { + // all I need is to get the pdf url but somehow + // firefox won't allow extensions to run content scripts on pdf https://bugzilla.mozilla.org/show_bug.cgi?id=1454760 + // so I set up a weird method to fix this issue by asking tab to give the url + // and then I can get the pdf url + const result = { + url: tab.url, + content: "", + type: "pdf" + } + resolve(result) + } } }) } diff --git a/src/public/_locales/da/messages.json b/src/public/_locales/da/messages.json index b0b239dd..378213ee 100644 --- a/src/public/_locales/da/messages.json +++ b/src/public/_locales/da/messages.json @@ -20,10 +20,10 @@ "contextRephrase": { "message": "Omskriv" }, - "contextTranslate" :{ + "contextTranslate": { "message": "Oversæt" }, "contextCustom": { "message": "Tilpasset" } -} \ No newline at end of file +} diff --git a/src/public/_locales/de/messages.json b/src/public/_locales/de/messages.json index 3da10c16..8a9a0aad 100644 --- a/src/public/_locales/de/messages.json +++ b/src/public/_locales/de/messages.json @@ -20,10 +20,10 @@ "contextRephrase": { "message": "Umformulieren" }, - "contextTranslate" :{ + "contextTranslate": { "message": "Übersetzen" }, "contextCustom": { "message": "Benutzerdefiniert" } -} \ No newline at end of file +} diff --git a/src/public/_locales/en/messages.json b/src/public/_locales/en/messages.json index cd347088..892f62ef 100644 --- a/src/public/_locales/en/messages.json +++ b/src/public/_locales/en/messages.json @@ -20,10 +20,10 @@ "contextRephrase": { "message": "Rephrase" }, - "contextTranslate" :{ + "contextTranslate": { "message": "Translate" }, "contextCustom": { "message": "Custom" } -} \ No newline at end of file +} diff --git a/src/public/_locales/fa/messages.json b/src/public/_locales/fa/messages.json index c193a32f..f956800e 100644 --- a/src/public/_locales/fa/messages.json +++ b/src/public/_locales/fa/messages.json @@ -20,7 +20,7 @@ "contextRephrase": { "message": "بازنویسی" }, - "contextTranslate" :{ + "contextTranslate": { "message": "ترجمه کردن" }, "contextCustom": { diff --git a/src/public/_locales/fr/messages.json b/src/public/_locales/fr/messages.json index 179752df..656eefc7 100644 --- a/src/public/_locales/fr/messages.json +++ b/src/public/_locales/fr/messages.json @@ -17,10 +17,10 @@ "contextRephrase": { "message": "Reformuler" }, - "contextTranslate" :{ + "contextTranslate": { "message": "Traduire" }, "contextCustom": { "message": "Personnalisé" } -} \ No newline at end of file +} diff --git a/src/public/_locales/it/messages.json b/src/public/_locales/it/messages.json index eaee088b..e37d5d26 100644 --- a/src/public/_locales/it/messages.json +++ b/src/public/_locales/it/messages.json @@ -17,7 +17,7 @@ "contextRephrase": { "message": "Riformula" }, - "contextTranslate" :{ + "contextTranslate": { "message": "Traduci" }, "contextCustom": { diff --git a/src/public/_locales/ja/messages.json b/src/public/_locales/ja/messages.json index 347ad7b3..15fb399a 100644 --- a/src/public/_locales/ja/messages.json +++ b/src/public/_locales/ja/messages.json @@ -9,18 +9,18 @@ "message": "チャットするためにCopilotを開く" }, "contextSummarize": { - "message": "要約" - }, - "contextExplain": { - "message": "説明" - }, - "contextRephrase": { - "message": "言い換え" - }, - "contextTranslate" :{ - "message": "翻訳" - }, - "contextCustom": { - "message": "カスタム" - } -} \ No newline at end of file + "message": "要約" + }, + "contextExplain": { + "message": "説明" + }, + "contextRephrase": { + "message": "言い換え" + }, + "contextTranslate": { + "message": "翻訳" + }, + "contextCustom": { + "message": "カスタム" + } +} diff --git a/src/public/_locales/ml/messages.json b/src/public/_locales/ml/messages.json index 4a6699a6..bbde1627 100644 --- a/src/public/_locales/ml/messages.json +++ b/src/public/_locales/ml/messages.json @@ -17,10 +17,10 @@ "contextRephrase": { "message": "പുനഃരൂപീകരിക്കുക" }, - "contextTranslate" :{ + "contextTranslate": { "message": "വിവർത്തനം ചെയ്യുക" }, "contextCustom": { "message": "ഇഷ്ടാനുസൃതം" } -} \ No newline at end of file +} diff --git a/src/public/_locales/no/messages.json b/src/public/_locales/no/messages.json index 1bb0b1f2..4ada7b8e 100644 --- a/src/public/_locales/no/messages.json +++ b/src/public/_locales/no/messages.json @@ -20,10 +20,10 @@ "contextRephrase": { "message": "Omskrive" }, - "contextTranslate" :{ + "contextTranslate": { "message": "Oversett" }, "contextCustom": { "message": "Tilpasset" } -} \ No newline at end of file +} diff --git a/src/public/_locales/ru/messages.json b/src/public/_locales/ru/messages.json index 61c6a1d2..9d41aaf4 100644 --- a/src/public/_locales/ru/messages.json +++ b/src/public/_locales/ru/messages.json @@ -17,10 +17,10 @@ "contextRephrase": { "message": "Перефразировать" }, - "contextTranslate" :{ + "contextTranslate": { "message": "Перевести" }, "contextCustom": { "message": "Пользовательский" } -} \ No newline at end of file +} diff --git a/src/public/_locales/sv/messages.json b/src/public/_locales/sv/messages.json new file mode 100644 index 00000000..414a9a89 --- /dev/null +++ b/src/public/_locales/sv/messages.json @@ -0,0 +1,29 @@ +{ + "extName": { + "message": "Page Assist - Ett webbaserat användargränssnitt för lokala AI-modeller" + }, + "extDescription": { + "message": "Använd dina lokalt körande AI-modeller för att hjälpa dig i din webbsurfning." + }, + "openSidePanelToChat": { + "message": "Öppna Copilot för att chatta" + }, + "openOptionToChat": { + "message": "Öppna Web UI för att chatta" + }, + "contextSummarize": { + "message": "Sammanfatta" + }, + "contextExplain": { + "message": "Förklara" + }, + "contextRephrase": { + "message": "Skriv om" + }, + "contextTranslate": { + "message": "Översätt" + }, + "contextCustom": { + "message": "Custom" + } +} diff --git a/src/public/_locales/zh_CN/messages.json b/src/public/_locales/zh_CN/messages.json index e9be275f..9d050c57 100644 --- a/src/public/_locales/zh_CN/messages.json +++ b/src/public/_locales/zh_CN/messages.json @@ -17,10 +17,10 @@ "contextRephrase": { "message": "改述" }, - "contextTranslate" :{ + "contextTranslate": { "message": "翻译" }, "contextCustom": { "message": "自定义" } -} \ No newline at end of file +} diff --git a/src/utils/latex.ts b/src/utils/latex.ts new file mode 100644 index 00000000..77f98ffc --- /dev/null +++ b/src/utils/latex.ts @@ -0,0 +1,19 @@ +export const preprocessLaTeX = (content: string) => { + let processedContent = content.replace( + /\\\[([\s\S]*?)\\\]/g, + (_, equation) => `$$${equation}$$` + ); + processedContent = processedContent.replace( + /\\\(([\s\S]*?)\\\)/g, + (_, equation) => `$${equation}$` + ); + processedContent = processedContent.replace( + /\\begin\{equation\}([\s\S]*?)\\end\{equation\}/g, + (_, equation) => `$$${equation}$$` + ); + processedContent = processedContent.replace( + /\\begin\{align\}([\s\S]*?)\\end\{align\}/g, + (_, equation) => `$$\\begin{aligned}${equation}\\end{aligned}$$` + ); + return processedContent; +} \ No newline at end of file diff --git a/wxt.config.ts b/wxt.config.ts index 5d06de7c..c5963abc 100644 --- a/wxt.config.ts +++ b/wxt.config.ts @@ -50,7 +50,7 @@ export default defineConfig({ outDir: "build", manifest: { - version: "1.3.1", + version: "1.3.2", name: process.env.TARGET === "firefox" ? "Page Assist - A Web UI for Local AI Models"