diff --git a/bun.lock b/bun.lock index 70bc97303ae1..5af63fc3b0f3 100644 --- a/bun.lock +++ b/bun.lock @@ -663,6 +663,7 @@ "ulid": "catalog:", "venice-ai-sdk-provider": "2.1.1", "vscode-jsonrpc": "8.2.1", + "waconector": "1.3.0", "web-tree-sitter": "0.25.10", "ws": "8.21.0", "xdg-basedir": "5.1.0", @@ -5556,6 +5557,8 @@ "vscode-uri": ["vscode-uri@3.1.0", "", {}, "sha512-/BpdSx+yCQGnCvecbyXdxHDkuk55/G3xwnC0GqY4gmQ3j+A+g8kzzgB4Nk/SINjqn6+waqw3EgbVF2QKExkRxQ=="], + "waconector": ["waconector@1.3.0", "", { "bin": { "waconector": "dist/cli/index.js" } }, "sha512-rj1+M2MLa11xErI2XSqMd03k4H1et4MZDzoz8jFj0fbsN1JxBxYviHnhxM/dRkIonoToNquc8sdr67b0X168YA=="], + "walk-up-path": ["walk-up-path@4.0.0", "", {}, "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A=="], "web-namespaces": ["web-namespaces@2.0.1", "", {}, "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ=="], diff --git a/packages/app/e2e/regression/session-todo-dock-navigation.spec.ts b/packages/app/e2e/regression/session-todo-dock-navigation.spec.ts index 55e71212753c..037fcd67209f 100644 --- a/packages/app/e2e/regression/session-todo-dock-navigation.spec.ts +++ b/packages/app/e2e/regression/session-todo-dock-navigation.spec.ts @@ -86,7 +86,12 @@ test("animates todo lifecycle without replaying it across session tabs", async ( await switchSession(page, otherID, otherTitle) await expect(dock).toHaveCount(0) - const returningOpen = sampleDock(page, 700) + // Was 700ms: under CI load the session-switch render can take long enough + // that the sampling window closes before the dock ever mounts, leaving + // zero "present" samples and failing on a load artifact rather than a + // real animation regression (observed 2026-09-09, all 3 attempts failing + // identically in one run — a systemic-load run, not a rare flake). + const returningOpen = sampleDock(page, 1_400) await switchSession(page, sourceID, sourceTitle) const openSamples = (await returningOpen).filter((sample) => sample.present) expect(openSamples.length).toBeGreaterThan(0) diff --git a/packages/app/src/app.tsx b/packages/app/src/app.tsx index dbb58221ca64..04fb9530a812 100644 --- a/packages/app/src/app.tsx +++ b/packages/app/src/app.tsx @@ -73,6 +73,7 @@ import { BatutaActivityFormPage } from "@/pages/batuta/activity-form" import { BatutaActivityLivePage } from "@/pages/batuta/activity-live" import { AgentUIPage } from "@/pages/agentui" import { AgentUIFormPage } from "@/pages/agentui-form" +import { AgentUIAuditPage } from "@/pages/agentui-audit" import { SettingsPage } from "@/pages/settings" import { LegacyHome } from "@/pages/home/legacy-home" @@ -663,6 +664,7 @@ function Routes(props: { serverScoped?: JSX.Element }) { + diff --git a/packages/app/src/components/batuta/model-picker-v2.tsx b/packages/app/src/components/batuta/model-picker-v2.tsx index d3bfecb9f6ae..0f48d9c92692 100644 --- a/packages/app/src/components/batuta/model-picker-v2.tsx +++ b/packages/app/src/components/batuta/model-picker-v2.tsx @@ -14,6 +14,16 @@ export interface ModelPickerV2Props { onChange: (value: string) => void /** When provided, the provider dropdown also lists these as selectable combos. */ combos?: { id: string; name: string }[] + /** + * Worktree to scope the provider catalog to. Without this, useProviders() + * falls back to the global catalog, which misses providers only connected + * per-project (e.g. Omniroute) — those still show in a real session's + * chat composer (project-scoped) but silently disappear from this picker. + * Pass the caller's own directory when one is available (AgentUI); other + * callers (Batuta, Memória) have no natural directory and keep the old + * global-catalog behavior by omitting this. + */ + directory?: string } function splitModel(value: string) { @@ -33,10 +43,21 @@ const selectClass = ` export const ModelPickerV2: Component = (props) => { const language = useLanguage() - const providers = useProviders(() => undefined) + const providers = useProviders(() => props.directory) + // Only providers actually connected (auth configured) with at least one + // model to pick — the full catalog (`providers.all()`) includes every + // provider opencode knows about, most of which aren't usable without + // setup, and would otherwise flood this dropdown with hundreds of dead + // options. A connected provider can still have zero synced models in this + // global (non-directory-scoped) catalog — Omniroute is one such case, + // since its catalog only populates once synced against a specific + // project — which would be a dead end if left selectable here. const providerList = createMemo(() => - Array.from(providers.all().values()).sort((a, b) => a.name.localeCompare(b.name)), + providers + .connected() + .filter((provider) => Object.keys(provider.models).length > 0) + .sort((a, b) => a.name.localeCompare(b.name)), ) const isCombo = createMemo(() => props.value.startsWith(COMBO_PREFIX)) const selectedComboID = createMemo(() => (isCombo() ? props.value.slice(COMBO_PREFIX.length) : "")) @@ -97,7 +118,7 @@ export const ModelPickerV2: Component = (props) => {
- MODEL_RENDER_CAP}> + 0}> = (props) => { openSandbox(agent)}> {language.t("settings.agentui.sandbox.open")} + } + aria-label={language.t("settings.agentui.audit.title")} + onClick={() => navigate(`/agentui/${agent.id}/audit`)} + /> = { + izapia: "izapia", + waha: "WAHA (self-hosted, Docker)", + evolution: "Evolution GO (self-hosted, Docker)", + zapi: "Z-API (SaaS)", + uazapi: "uazapi (SaaS)", + whapi: "Whapi.Cloud (SaaS)", + wuzapi: "Wuzapi (self-hosted, Docker)", + quepasa: "QuePasa (self-hosted, Docker)", + wppconnect: "WPPConnect Server (self-hosted, Docker)", +} + +// Painel/dashboard oficial do provider, onde a pessoa consegue criar a conta +// e pegar as credenciais pedidas nos campos abaixo. Só preenchido quando +// existe uma URL confirmada (não um chute) — providers self-hosted não têm +// uma, já que rodam no servidor da própria pessoa. +export const WHATSAPP_PROVIDER_LINKS: Partial> = { + izapia: "https://app.izapia.com/login", +} + +export const WHATSAPP_PROVIDER_FIELDS: Record = { + waha: [ + { key: "baseUrl", required: true, label: "URL base (ex.: http://localhost:3000)" }, + { key: "apiKey", required: true, label: "API Key (X-Api-Key)" }, + { key: "session", required: false, label: "Nome da sessão (padrão: default)" }, + ], + evolution: [ + { key: "baseUrl", required: true, label: "URL base do servidor Evolution GO" }, + { key: "apiKey", required: true, label: "API Key da instância" }, + ], + zapi: [ + { key: "instanceId", required: true, label: "Instance ID" }, + { key: "token", required: true, label: "Token da instância" }, + { key: "clientToken", required: false, label: "Client-Token (se ativado na conta)" }, + ], + uazapi: [ + { key: "baseUrl", required: true, label: "URL base (ex.: https://minhaempresa.uazapi.com)" }, + { key: "token", required: true, label: "Token da instância" }, + ], + whapi: [{ key: "token", required: true, label: "Token do canal (Bearer)" }], + wuzapi: [ + { key: "baseUrl", required: true, label: "URL base do servidor Wuzapi" }, + { key: "token", required: true, label: "Token do usuário" }, + ], + quepasa: [ + { key: "baseUrl", required: true, label: "URL base da instância QuePasa" }, + { key: "token", required: true, label: "Token da instância" }, + ], + wppconnect: [ + { key: "baseUrl", required: true, label: "URL base do servidor WPPConnect" }, + { key: "session", required: true, label: "Nome da sessão" }, + { key: "token", required: true, label: "Token Bearer da sessão" }, + ], + // No "sid" field here — izapia is multi-session, picked via the "buscar + // sessões" checkboxes in agentui-form.tsx (WhatsAppChannelBinding.sessionIds), + // not typed in as config. + izapia: [{ key: "apiKey", required: true, label: "API key do tenant" }], +} diff --git a/packages/app/src/i18n/am.ts b/packages/app/src/i18n/am.ts index cd9fc4749131..dc3c34f09342 100644 --- a/packages/app/src/i18n/am.ts +++ b/packages/app/src/i18n/am.ts @@ -816,6 +816,7 @@ export const dict = { "common.dismiss": "አሰናብት", "common.moreCountSuffix": " (+{{count}} ተጨማሪ)", "common.requestFailed": "ጥያቄው አልተሳካም", + "common.optional": "አማራጭ", "common.moreOptions": "ተጨማሪ አማራጮች", "common.learnMore": "ተጨማሪ ለመረዳት", "common.rename": "ዳግም ስም", @@ -1418,6 +1419,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "ለዚህ ወኪል የራሱን የቴሌግራም ቦት ለመስጠት ይህን ገጽ ከተገናኘ ፕሮጀክት ይክፈቱ።", + "settings.agentui.error.whatsappIncomplete": "ይህን ገጽ ከተገናኘ ፕሮጀክት ይክፈቱ እና ለተመረጠው WhatsApp አቅራቢ ሁሉንም አስፈላጊ መስኮች ይሙሉ።", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1427,12 +1429,53 @@ export const dict = { "settings.agentui.ai.generate": "ፍጠር", "settings.agentui.ai.generating": "በመፍጠር ላይ…", "settings.agentui.ai.toast.generated": "ረቂቅ ተፈጥሯል — ከማስቀመጥዎ በፊት ይከልሱ", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "የቦት ቶከን (አማራጭ — ሁለንተናዊ ቦትን ለማጋራት ባዶ ይተዉት)", "settings.agentui.field.telegramToken.hint": "ለዚህ ወኪል የራሱ የተወሰነ የቴሌግራም ቦት ለመስጠት ከ@BotFather ቶከን ይለጥፉ። ባዶ ከተተወ በቅንብሮች → ውህደቶች ውስጥ ባለው የጋራ ቦት በኩል በራሱ ትዕዛዝ ቅድመ ቅጥያ ይደረሳል።", + "settings.agentui.field.whatsapp": "በWhatsApp ይመልሱ", + "settings.agentui.field.whatsapp.hint": "ኦፊሴላዊ ያልሆነ WhatsApp API (በ waconector በኩል) ይጠቀማል — አቅራቢ ይምረጡ እና የግንኙነት ዝርዝሮችን ይሙሉ። ራስን-ያስተናገዱ አቅራቢዎች የራሳቸው ሰርቨር/ኮንቴይነር ተለይተው እንዲሰራ ይፈልጋሉ፤ ይህ ከዚያ ጋር ብቻ ይገናኛል።", + "settings.agentui.field.whatsapp.webhookUrl": "የዌብሁክ URL — በአቅራቢው ዳሽቦርድ ውስጥ ይለጥፉ", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "በአቅራቢው በኩል መዋቀር ያለበት የዌብሁክ URL ካስቀመጡ በኋላ እዚህ ይታያል።", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/ar.ts b/packages/app/src/i18n/ar.ts index a4c99322b5b7..8e82bc34fc3c 100644 --- a/packages/app/src/i18n/ar.ts +++ b/packages/app/src/i18n/ar.ts @@ -802,6 +802,7 @@ export const dict = { "common.closeTab": "إغلاق علامة التبويب", "common.dismiss": "إهمال", "common.requestFailed": "فشل الطلب", + "common.optional": "اختياري", "common.moreOptions": "مزيد من الخيارات", "common.learnMore": "اطّلع على المزيد", "common.rename": "إعادة تسمية", @@ -1459,6 +1460,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "افتح هذه الصفحة من مشروع متصل لمنح هذا الوكيل بوت تيليجرام خاصًا به.", + "settings.agentui.error.whatsappIncomplete": "افتح هذه الصفحة من مشروع متصل واملأ كل الحقول المطلوبة لمزود WhatsApp المحدد.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1468,12 +1470,53 @@ export const dict = { "settings.agentui.ai.generate": "إنشاء", "settings.agentui.ai.generating": "جارٍ الإنشاء…", "settings.agentui.ai.toast.generated": "تم إنشاء المسودة — راجعها قبل الحفظ", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "رمز البوت (اختياري — اتركه فارغًا لمشاركة البوت العام)", "settings.agentui.field.telegramToken.hint": "الصق رمزًا من @BotFather لمنح هذا الوكيل بوت تيليجرام مخصصًا له. اتركه فارغًا للوصول إليه عبر البوت المشترك في الإعدادات ← التكاملات، باستخدام بادئة الأمر الخاصة به.", + "settings.agentui.field.whatsapp": "الرد على واتساب", + "settings.agentui.field.whatsapp.hint": "يستخدم واجهة برمجة تطبيقات واتساب غير رسمية (عبر waconector) — اختر مزودًا واملأ بيانات الاتصال. المزودات المستضافة ذاتيًا تحتاج خادمها/حاويتها الخاصة تعمل بشكل منفصل؛ هذا فقط يتصل بها.", + "settings.agentui.field.whatsapp.webhookUrl": "رابط الويب هوك — الصقه في لوحة تحكم المزود", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "رابط الويب هوك الذي يجب إعداده لدى المزود يظهر هنا بعد الحفظ.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/az.ts b/packages/app/src/i18n/az.ts index 950eb5943b65..9c36d63fb309 100644 --- a/packages/app/src/i18n/az.ts +++ b/packages/app/src/i18n/az.ts @@ -841,6 +841,7 @@ export const dict = { "common.dismiss": "Bağla", "common.moreCountSuffix": " (+{{count}} daha)", "common.requestFailed": "Sorğu uğursuz oldu", + "common.optional": "istəyə bağlı", "common.moreOptions": "Daha çox seçim", "common.learnMore": "Ətraflı öyrən", "common.rename": "Adını dəyiş", @@ -1456,6 +1457,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Bu agentə öz Telegram botunu vermək üçün bu səhifəni qoşulmuş layihədən açın.", + "settings.agentui.error.whatsappIncomplete": "Bu səhifəni qoşulmuş layihədən açın və seçilmiş WhatsApp provayderi üçün bütün tələb olunan sahələri doldurun.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1465,12 +1467,53 @@ export const dict = { "settings.agentui.ai.generate": "Yarat", "settings.agentui.ai.generating": "Yaradılır…", "settings.agentui.ai.toast.generated": "Qaralama yaradıldı — yadda saxlamazdan əvvəl nəzərdən keçirin", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot tokeni (istəyə bağlı — qlobal botu paylaşmaq üçün boş buraxın)", "settings.agentui.field.telegramToken.hint": "Bu agentə xüsusi Telegram botu vermək üçün @BotFather-dən tokeni yapışdırın. Boş buraxsanız, Ayarlar → İnteqrasiyalar bölməsindəki ortaq botla, öz əmr prefiksi ilə əlçatan olacaq.", + "settings.agentui.field.whatsapp": "WhatsApp-da cavabla", + "settings.agentui.field.whatsapp.hint": "Qeyri-rəsmi WhatsApp API-dən (waconector vasitəsilə) istifadə edir — provayder seçin və bağlantı detallarını doldurun. Özü-host edilən provayderlər öz serverini/konteynerini ayrıca işlək tələb edir; bu yalnız ona qoşulur.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL-i — provayderin panelinə yapışdırın", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Provayder tərəfində sazlanmalı webhook URL-i yadda saxladıqdan sonra burada görünür.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/bg.ts b/packages/app/src/i18n/bg.ts index 7645ff7658b1..4ff2218ad3a9 100644 --- a/packages/app/src/i18n/bg.ts +++ b/packages/app/src/i18n/bg.ts @@ -838,6 +838,7 @@ export const dict = { "common.dismiss": "Отхвърляне", "common.moreCountSuffix": "(+{{count}} още)", "common.requestFailed": "Неуспешна заявка", + "common.optional": "по избор", "common.moreOptions": "Още опции", "common.learnMore": "Научете повече", "common.rename": "Преименуване", @@ -1458,6 +1459,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Отворете тази страница от свързан проект, за да дадете на този агент собствен Telegram бот.", + "settings.agentui.error.whatsappIncomplete": "Отворете тази страница от свързан проект и попълнете всички задължителни полета за избрания доставчик на WhatsApp.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1467,12 +1469,53 @@ export const dict = { "settings.agentui.ai.generate": "Генерирай", "settings.agentui.ai.generating": "Генериране…", "settings.agentui.ai.toast.generated": "Чернова е генерирана — прегледайте преди запис", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Токен на бота (по избор — оставете празно, за да споделяте глобалния бот)", "settings.agentui.field.telegramToken.hint": "Поставете токен от @BotFather, за да дадете на този агент собствен, посветен Telegram бот. Оставете празно, за да се достига чрез споделения бот в Настройки → Интеграции, чрез неговия команден префикс.", + "settings.agentui.field.whatsapp": "Отговори в WhatsApp", + "settings.agentui.field.whatsapp.hint": "Използва неофициално WhatsApp API (чрез waconector) — изберете доставчик и попълнете данните за връзка. Самостоятелно хостваните доставчици се нуждаят от собствен сървър/контейнер, работещ отделно; това само се свързва с него.", + "settings.agentui.field.whatsapp.webhookUrl": "URL адрес на webhook — поставете го в таблото на доставчика", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL адресът на webhook за конфигуриране при доставчика се показва тук след запис.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/bn.ts b/packages/app/src/i18n/bn.ts index f02a91c9ad61..47e8049d56b8 100644 --- a/packages/app/src/i18n/bn.ts +++ b/packages/app/src/i18n/bn.ts @@ -831,6 +831,7 @@ export const dict: Record = { "common.dismiss": "খারিজ", "common.moreCountSuffix": "(+{{count}} আরো)", "common.requestFailed": "অনুরোধ ব্যর্থ হয়েছে", + "common.optional": "ঐচ্ছিক", "common.moreOptions": "আরও বিকল্প", "common.learnMore": "আরও জানুন", "common.rename": "নাম পরিবর্তন করুন", @@ -1440,6 +1441,7 @@ export const dict: Record = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "এই এজেন্টকে নিজস্ব টেলিগ্রাম বট দিতে সংযুক্ত প্রকল্প থেকে এই পৃষ্ঠাটি খুলুন।", + "settings.agentui.error.whatsappIncomplete": "একটি সংযুক্ত প্রকল্প থেকে এই পৃষ্ঠাটি খুলুন এবং নির্বাচিত WhatsApp প্রদানকারীর জন্য সমস্ত প্রয়োজনীয় ক্ষেত্র পূরণ করুন।", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1449,12 +1451,53 @@ export const dict: Record = { "settings.agentui.ai.generate": "তৈরি করুন", "settings.agentui.ai.generating": "তৈরি হচ্ছে…", "settings.agentui.ai.toast.generated": "খসড়া তৈরি হয়েছে — সংরক্ষণের আগে পর্যালোচনা করুন", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "বট টোকেন (ঐচ্ছিক — গ্লোবাল বট শেয়ার করতে খালি রাখুন)", "settings.agentui.field.telegramToken.hint": "এই এজেন্টকে নিজস্ব উৎসর্গীকৃত টেলিগ্রাম বট দিতে @BotFather থেকে একটি টোকেন পেস্ট করুন। সেটিংস → ইন্টিগ্রেশনে থাকা শেয়ার করা বটের মাধ্যমে পৌঁছাতে খালি রাখুন, এর কমান্ড ট্রিগার ব্যবহার করে।", + "settings.agentui.field.whatsapp": "WhatsApp-এ উত্তর দিন", + "settings.agentui.field.whatsapp.hint": "একটি অনানুষ্ঠানিক WhatsApp API ব্যবহার করে (waconector এর মাধ্যমে) — একটি প্রদানকারী বেছে নিন এবং সংযোগের বিবরণ পূরণ করুন। স্ব-হোস্টেড প্রদানকারীদের নিজস্ব সার্ভার/কন্টেইনার আলাদাভাবে চালানো প্রয়োজন; এটি শুধু তার সাথে সংযোগ করে।", + "settings.agentui.field.whatsapp.webhookUrl": "ওয়েবহুক URL — প্রদানকারীর ড্যাশবোর্ডে পেস্ট করুন", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "সংরক্ষণের পরে প্রদানকারীর পক্ষ থেকে কনফিগার করার জন্য ওয়েবহুক URL এখানে প্রদর্শিত হয়।", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/br.ts b/packages/app/src/i18n/br.ts index 60862d1818dd..a89dc4c59cc0 100644 --- a/packages/app/src/i18n/br.ts +++ b/packages/app/src/i18n/br.ts @@ -869,6 +869,7 @@ export const dict = { "common.closeTab": "Fechar aba", "common.dismiss": "Descartar", "common.requestFailed": "Requisição falhou", + "common.optional": "opcional", "common.moreOptions": "Mais opções", "common.learnMore": "Saiba mais", "common.rename": "Renomear", @@ -905,6 +906,7 @@ export const dict = { "settings.agentui.empty": "Nenhum agente ainda.", "settings.agentui.error.incomplete": "Dê um nome ao agente e escolha um modelo.", "settings.agentui.error.telegramNeedsProject": "Abra esta página a partir de um projeto conectado para dar um bot próprio do Telegram a este agente.", + "settings.agentui.error.whatsappIncomplete": "Abra esta página a partir de um projeto conectado e preencha todos os campos obrigatórios do provedor de WhatsApp selecionado.", "settings.agentui.toast.saved": "Agente salvo", "settings.agentui.dialog.addTitle": "Criar agente", "settings.agentui.dialog.editTitle": "Editar agente", @@ -920,6 +922,47 @@ export const dict = { "settings.agentui.field.telegram": "Responder no Telegram", "settings.agentui.field.telegramToken.placeholder": "Token do bot (opcional — deixe vazio para usar o bot global)", "settings.agentui.field.telegramToken.hint": "Cole um token do @BotFather para dar a este agente seu próprio bot dedicado do Telegram. Deixe vazio para responder pelo bot compartilhado em Configurações → Integrações, usando o prefixo de comando.", + "settings.agentui.field.whatsapp": "Responder no WhatsApp", + "settings.agentui.tabs.general": "Geral", + "settings.agentui.tabs.channels": "Canais", + "settings.agentui.tabs.tools": "Ferramentas", + "settings.agentui.tabs.knowledge": "Conhecimento", + "settings.agentui.tabs.audit": "Auditoria", + "settings.agentui.audit.title": "Histórico de mensagens", + "settings.agentui.audit.refresh": "Atualizar", + "settings.agentui.audit.loading": "Carregando…", + "settings.agentui.audit.needsSave": "Salve o agente primeiro para ver o histórico de mensagens.", + "settings.agentui.audit.empty": "Nenhuma mensagem registrada ainda.", + "settings.agentui.audit.blocked": "Bloqueada", + "settings.agentui.audit.incoming": "Recebida", + "settings.agentui.audit.outgoing": "Respondida", + "settings.agentui.field.mcpServers": "Servidores MCP", + "settings.agentui.field.mcpServers.hint": "Permite que este agente use as ferramentas dos servidores MCP abaixo, conectados ao mesmo projeto dos seus canais. Desligado por padrão — agentes são só conversacionais até você ativar um.", + "settings.agentui.field.mcpServers.empty": "Nenhum servidor MCP configurado neste projeto ainda. Adicione um em Configurações → MCP primeiro.", + "settings.agentui.field.mcpServers.noDirectory": "Abra um projeto primeiro para ver seus servidores MCP.", + "settings.agentui.field.whatsapp.providerLink": "Abrir painel do {{provider}} →", + "settings.agentui.field.whatsapp.izapiaSessions.label": "Sessões do WhatsApp (selecione uma ou mais)", + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Buscar sessões", + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Buscando…", + "settings.agentui.field.whatsapp.izapiaSessions.empty": "Nenhuma sessão encontrada para essa API key.", + "settings.agentui.field.whatsapp.izapiaGroups.label": "Grupos", + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Mensagens diretas são sempre respondidas. Marque os grupos em que o agente também deve responder — grupos desmarcados são ignorados.", + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Buscar grupos", + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Buscando…", + "settings.agentui.field.whatsapp.izapiaGroups.empty": "Nenhum grupo encontrado para as sessões selecionadas.", + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Opção mais simples se você já tem o Tailscale rodando nesta máquina e no servidor do provedor: use o IP Tailscale desta máquina direto, sem precisar de túnel.", + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Usar IP Tailscale", + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detectando…", + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "Nenhum IP Tailscale encontrado. O Tailscale está instalado e rodando?", + "settings.agentui.field.whatsapp.tunnel.hint": "A URL deste servidor é local (127.0.0.1/localhost) — o provedor não consegue chamá-la de volta para entregar mensagens. Inicie um túnel público para resolver isso.", + "settings.agentui.field.whatsapp.tunnel.start": "Iniciar túnel público", + "settings.agentui.field.whatsapp.tunnel.starting": "Iniciando…", + "settings.agentui.field.whatsapp.tunnel.active": "Túnel público ativo: {{url}} — a URL do webhook abaixo já está usando ele.", + "settings.agentui.field.whatsapp.tunnel.error": "Não consegui iniciar o túnel. O cloudflared está instalado?", + "settings.agentui.field.whatsapp.hint": "Usa uma API não oficial de WhatsApp (via waconector) — escolha um provedor e preencha os dados de conexão. Provedores self-hosted (WAHA, Evolution GO, Wuzapi, QuePasa, WPPConnect) precisam do próprio servidor/container rodando separadamente; isso só conecta a ele.", + "settings.agentui.field.whatsapp.webhookUrl": "URL do webhook — cole no painel do provedor", + "settings.agentui.field.whatsapp.webhookSecret": "Secret do webhook — alguns provedores (ex: izapia) pedem isso separadamente", + "settings.agentui.field.whatsapp.webhookAfterSave": "A URL do webhook para configurar no provedor aparece aqui depois que você salvar.", "settings.agentui.field.commandTriggers": "Prefixos de comando (separados por espaço, ex.: ! #)", "settings.agentui.field.guardrails": "Guardrails", "settings.agentui.field.guardrailsLevel": "Nível de guardrails", diff --git a/packages/app/src/i18n/bs.ts b/packages/app/src/i18n/bs.ts index 8f1d15ec8b6a..43da540d09ea 100644 --- a/packages/app/src/i18n/bs.ts +++ b/packages/app/src/i18n/bs.ts @@ -865,6 +865,7 @@ export const dict = { "common.closeTab": "Zatvori karticu", "common.dismiss": "Odbaci", "common.requestFailed": "Zahtjev nije uspio", + "common.optional": "opcionalno", "common.moreOptions": "Više opcija", "common.learnMore": "Saznaj više", "common.rename": "Preimenuj", @@ -1545,6 +1546,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Otvorite ovu stranicu iz povezanog projekta da biste ovom agentu dali vlastiti Telegram bot.", + "settings.agentui.error.whatsappIncomplete": "Otvorite ovu stranicu iz povezanog projekta i popunite sva obavezna polja za odabranog WhatsApp dobavljača.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1554,12 +1556,53 @@ export const dict = { "settings.agentui.ai.generate": "Generiši", "settings.agentui.ai.generating": "Generisanje…", "settings.agentui.ai.toast.generated": "Nacrt je generisan — pregledajte prije spremanja", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token bota (opcionalno — ostavite prazno za dijeljenje globalnog bota)", "settings.agentui.field.telegramToken.hint": "Zalijepite token od @BotFather da biste ovom agentu dali vlastiti namjenski Telegram bot. Ostavite prazno da bude dostupan preko zajedničkog bota u Postavke → Integracije, koristeći njegov prefiks komande.", + "settings.agentui.field.whatsapp": "Odgovori na WhatsAppu", + "settings.agentui.field.whatsapp.hint": "Koristi neslužbeni WhatsApp API (putem waconector) — odaberite dobavljača i popunite podatke za povezivanje. Samostalno hostovani dobavljači zahtijevaju vlastiti server/kontejner koji radi odvojeno; ovo se samo povezuje s njim.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhooka — nalijepite ga u kontrolnu ploču dobavljača", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL webhooka za konfiguraciju kod dobavljača pojavljuje se ovdje nakon spremanja.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/ca.ts b/packages/app/src/i18n/ca.ts index 472a22e8e80b..7bb896c93975 100644 --- a/packages/app/src/i18n/ca.ts +++ b/packages/app/src/i18n/ca.ts @@ -842,6 +842,7 @@ export const dict = { "common.dismiss": "Descartar", "common.moreCountSuffix": " (+{{count}} més)", "common.requestFailed": "La sol·licitud ha fallat", + "common.optional": "opcional", "common.moreOptions": "Més opcions", "common.learnMore": "Més informació", "common.rename": "Canvia el nom", @@ -1461,6 +1462,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Obre aquesta pàgina des d'un projecte connectat per donar a aquest agent el seu propi bot de Telegram.", + "settings.agentui.error.whatsappIncomplete": "Obre aquesta pàgina des d'un projecte connectat i omple tots els camps obligatoris del proveïdor de WhatsApp seleccionat.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1470,12 +1472,53 @@ export const dict = { "settings.agentui.ai.generate": "Genera", "settings.agentui.ai.generating": "Generant…", "settings.agentui.ai.toast.generated": "Esborrany generat — revisa'l abans de desar", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Testimoni del bot (opcional — deixa buit per compartir el bot global)", "settings.agentui.field.telegramToken.hint": "Enganxa un testimoni de @BotFather per donar a aquest agent el seu propi bot dedicat de Telegram. Deixa-ho buit per accedir-hi mitjançant el bot compartit a Configuració → Integracions, usant el seu prefix d'ordre.", + "settings.agentui.field.whatsapp": "Respon a WhatsApp", + "settings.agentui.field.whatsapp.hint": "Utilitza una API no oficial de WhatsApp (via waconector) — tria un proveïdor i omple les dades de connexió. Els proveïdors autoallotjats necessiten el seu propi servidor/contenidor en execució per separat; això només s'hi connecta.", + "settings.agentui.field.whatsapp.webhookUrl": "URL del webhook — enganxa-la al tauler del proveïdor", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "La URL del webhook per configurar al proveïdor apareix aquí després de desar.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/cs.ts b/packages/app/src/i18n/cs.ts index 1ef60e8c9db5..4e6a55a1f4fd 100644 --- a/packages/app/src/i18n/cs.ts +++ b/packages/app/src/i18n/cs.ts @@ -837,6 +837,7 @@ export const dict = { "common.dismiss": "Odmítnout", "common.moreCountSuffix": " (+{{count}} další)", "common.requestFailed": "Požadavek se nezdařil", + "common.optional": "volitelné", "common.moreOptions": "Více možností", "common.learnMore": "Zjistěte více", "common.rename": "Přejmenovat", @@ -1451,6 +1452,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Otevřete tuto stránku z připojeného projektu, abyste tomuto agentovi dali vlastního Telegram bota.", + "settings.agentui.error.whatsappIncomplete": "Otevřete tuto stránku z připojeného projektu a vyplňte všechna povinná pole pro vybraného poskytovatele WhatsApp.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1460,12 +1462,53 @@ export const dict = { "settings.agentui.ai.generate": "Vygenerovat", "settings.agentui.ai.generating": "Generuje se…", "settings.agentui.ai.toast.generated": "Návrh vygenerován — zkontrolujte před uložením", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token bota (volitelné — nechte prázdné pro sdílení globálního bota)", "settings.agentui.field.telegramToken.hint": "Vložte token od @BotFather, abyste tomuto agentovi dali vlastního vyhrazeného Telegram bota. Nechte prázdné pro přístup přes sdíleného bota v Nastavení → Integrace, pomocí jeho příkazové předpony.", + "settings.agentui.field.whatsapp": "Odpovídat na WhatsApp", + "settings.agentui.field.whatsapp.hint": "Používá neoficiální WhatsApp API (přes waconector) — vyberte poskytovatele a vyplňte údaje o připojení. Self-hosted poskytovatelé potřebují vlastní server/kontejner spuštěný samostatně; toto se k němu pouze připojuje.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhooku — vložte jej do panelu poskytovatele", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL webhooku ke konfiguraci u poskytovatele se zobrazí zde po uložení.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/da.ts b/packages/app/src/i18n/da.ts index 5e3626fca1d4..21257302f3ce 100644 --- a/packages/app/src/i18n/da.ts +++ b/packages/app/src/i18n/da.ts @@ -742,6 +742,7 @@ export const dict = { "common.closeTab": "Luk fane", "common.dismiss": "Afvis", "common.requestFailed": "Forespørgsel mislykkedes", + "common.optional": "valgfrit", "common.moreOptions": "Flere muligheder", "common.learnMore": "Lær mere", "common.rename": "Omdøb", @@ -1536,6 +1537,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Åbn denne side fra et forbundet projekt for at give denne agent sin egen Telegram-bot.", + "settings.agentui.error.whatsappIncomplete": "Åbn denne side fra et forbundet projekt, og udfyld alle påkrævede felter for den valgte WhatsApp-udbyder.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1545,12 +1547,53 @@ export const dict = { "settings.agentui.ai.generate": "Generer", "settings.agentui.ai.generating": "Genererer…", "settings.agentui.ai.toast.generated": "Udkast genereret — gennemgå før du gemmer", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot-token (valgfrit — lad stå tomt for at dele den globale bot)", "settings.agentui.field.telegramToken.hint": "Indsæt et token fra @BotFather for at give denne agent sin egen dedikerede Telegram-bot. Lad stå tomt for at nå den via den delte bot i Indstillinger → Integrationer, med dens kommandopræfiks.", + "settings.agentui.field.whatsapp": "Svar på WhatsApp", + "settings.agentui.field.whatsapp.hint": "Bruger en uofficiel WhatsApp-API (via waconector) — vælg en udbyder, og udfyld forbindelsesoplysningerne. Selv-hostede udbydere kræver deres egen server/container kørende separat; dette forbinder blot til den.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook-URL — indsæt den i udbyderens dashboard", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Webhook-URL'en, der skal konfigureres hos udbyderen, vises her efter du gemmer.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/de.ts b/packages/app/src/i18n/de.ts index ecb6b2479a63..e98f1572f01c 100644 --- a/packages/app/src/i18n/de.ts +++ b/packages/app/src/i18n/de.ts @@ -695,6 +695,7 @@ export const dict = { "common.closeTab": "Tab schließen", "common.dismiss": "Verwerfen", "common.requestFailed": "Anfrage fehlgeschlagen", + "common.optional": "optional", "common.moreOptions": "Weitere Optionen", "common.learnMore": "Mehr erfahren", "common.rename": "Umbenennen", @@ -1473,6 +1474,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Öffne diese Seite aus einem verbundenen Projekt, um diesem Agenten einen eigenen Telegram-Bot zu geben.", + "settings.agentui.error.whatsappIncomplete": "Öffne diese Seite aus einem verbundenen Projekt und fülle alle erforderlichen Felder für den gewählten WhatsApp-Anbieter aus.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1482,12 +1484,53 @@ export const dict = { "settings.agentui.ai.generate": "Generieren", "settings.agentui.ai.generating": "Wird generiert…", "settings.agentui.ai.toast.generated": "Entwurf erstellt — vor dem Speichern überprüfen", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot-Token (optional — leer lassen, um den globalen Bot zu teilen)", "settings.agentui.field.telegramToken.hint": "Füge ein Token von @BotFather ein, um diesem Agenten einen eigenen dedizierten Telegram-Bot zu geben. Leer lassen, um ihn über den gemeinsamen Bot in Einstellungen → Integrationen mit seinem Befehlspräfix zu erreichen.", + "settings.agentui.field.whatsapp": "Auf WhatsApp antworten", + "settings.agentui.field.whatsapp.hint": "Nutzt eine inoffizielle WhatsApp-API (über waconector) — wähle einen Anbieter und fülle die Verbindungsdaten aus. Selbst gehostete Anbieter benötigen einen eigenen, separat laufenden Server/Container; dies verbindet sich nur damit.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook-URL — in das Dashboard des Anbieters einfügen", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Die beim Anbieter zu konfigurierende Webhook-URL erscheint hier nach dem Speichern.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/dv.ts b/packages/app/src/i18n/dv.ts index 9dda98469f90..554246e1cf1e 100644 --- a/packages/app/src/i18n/dv.ts +++ b/packages/app/src/i18n/dv.ts @@ -845,6 +845,7 @@ export const dict = { "common.dismiss": "ދުރުކޮށްލުން", "common.moreCountSuffix": " (+{{count}} އިތުރަށް)", "common.requestFailed": "ރިކުއެސްޓް ފެއިލްވިއެވެ", + "common.optional": "އިޚްތިޔާރީ", "common.moreOptions": "އިތުރު އިޚްތިޔާރުތަކެކެވެ", "common.learnMore": "އިތުރަށް ދަސްކުރައްވާށެވެ", "common.rename": "ނަން ބަދަލުކޮށްލާށެވެ", @@ -1465,6 +1466,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "މި އެޖެންޓަށް އަމިއްލަ ޓެލެގްރާމް ބޮޓެއް ދިނުމަށް، ކަނެކްޓް ކުރެވިފައިވާ ޕްރޮޖެކްޓަކުން މި ޞަފްޙާ ހުޅުވާ.", + "settings.agentui.error.whatsappIncomplete": "ކަނެކްޓް ކުރެވިފައިވާ ޕްރޮޖެކްޓަކުން މި ޞަފްޙާ ހުޅުވާ އަދި ހޮވިފައިވާ WhatsApp ފޯރުކޮށްދޭ ފަރާތުގެ ހުރިހާ ބޭނުންވާ ފީލްޑްތައް ފުރިހަމަ ކުރޭ.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1474,12 +1476,53 @@ export const dict = { "settings.agentui.ai.generate": "އުފައްދާ", "settings.agentui.ai.generating": "އުފައްދަނީ…", "settings.agentui.ai.toast.generated": "ޑްރާފްޓް އުފެއްދިއްޖެ — ސޭވް ކުރުމުގެ ކުރިން ރިވިއު ކުރޭ", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "ބޮޓް ޓޯކަން (އިޚްތިޔާރީ — ގްލޯބަލް ބޮޓް ޝެއަރ ކުރުމަށް ހުސްކޮށް ބަހައްޓާ)", "settings.agentui.field.telegramToken.hint": "މި އެޖެންޓަށް އަމިއްލަ ޓެލެގްރާމް ބޮޓެއް ދިނުމަށް @BotFather އިން ޓޯކަނެއް ޕޭސްޓް ކުރޭ. ހުސްކޮށް ބެހެއްޓުމުން ސެޓިންގްސް → އިންޓަގްރޭޝަންސްގައި ހުންނަ ޝެއަރޑް ބޮޓް މެދުވެރިކޮށް، އޭގެ ކޮމާންޑް ޓްރިގާ ބޭނުންކޮށްގެން ފޯރުކޮށްދެވޭނެ.", + "settings.agentui.field.whatsapp": "ވަޓްސްއެޕްގައި ޖަވާބުދޭ", + "settings.agentui.field.whatsapp.hint": "ރަސްމީ ނޫން WhatsApp API އެއް ބޭނުންކުރެވޭ (waconector މެދުވެރިކޮށް) — ފޯރުކޮށްދޭ ފަރާތެއް ހޮވާ އަދި ކަނެކްޝަން ތަފްޞީލްތައް ފުރިހަމަ ކުރޭ. ސެލްފް-ހޯސްޓެޑް ފޯރުކޮށްދޭ ފަރާތްތަކަށް ވަކިން ސާވަރ/ކޮންޓެއިނަރެއް ބޭނުންވޭ.", + "settings.agentui.field.whatsapp.webhookUrl": "ވެބްހުކް ޔޫއާރްއެލް — ފޯރުކޮށްދޭ ފަރާތުގެ ޑޭޝްބޯޑަށް ފޭސްޓް ކުރޭ", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "ފޯރުކޮށްދޭ ފަރާތުގައި ސެޓަޕް ކުރަންޖެހޭ ވެބްހުކް ޔޫއާރްއެލް ސޭވް ކުރުމަށްފަހު މިތާ ފެންނާނެ.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/dz.ts b/packages/app/src/i18n/dz.ts index bd2a55901955..3ee97f6cc41a 100644 --- a/packages/app/src/i18n/dz.ts +++ b/packages/app/src/i18n/dz.ts @@ -846,6 +846,7 @@ export const dict: Record = { "common.dismiss": "ཁུངས༌མེད༌བརྩི༌ནི", "common.moreCountSuffix": "(+{{count}} མང་།", "common.requestFailed": "ཞུ་བ་འཐུས་ཤོར་འབྱུང་ཡོདཔ།", + "common.optional": "དགའ་གདམ་", "common.moreOptions": "གདམ་ཁ་མང་བ།", "common.learnMore": "ཁ་གསལ་ཤེས།", "common.rename": "མིང་བསྒྱུར།", @@ -1469,6 +1470,7 @@ export const dict: Record = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "འ་ཨེན་ཊི་འདི་ལུ་རང་གི་ཊེལེགིརམ་བོཊ་སྤྲོད་ནི་དོན་ལས་མཐུད་ཡོད་པའི་ལས་འགུལ་ནང་ལས་ཤོག་ལེབ་འདི་ཁ་ཕྱེ།", + "settings.agentui.error.whatsappIncomplete": "མཐུད་ཡོད་པའི་ལས་འགུལ་ནང་ལས་ཤོག་ལེབ་འདི་ཁ་ཕྱེ་ཞིནམ་ འདེམས་བཟུང་ WhatsApp ཞབས་ཏོག་སྤྲོད་མིའི་དོན་ལས་གནད་སྤྱོད་ཀྱི་ས་སྒོ་ཆ་མཉམ་བཀང་།", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1478,12 +1480,53 @@ export const dict: Record = { "settings.agentui.ai.generate": "བཟོ་", "settings.agentui.ai.generating": "བཟོ་བཞིན་འདུག…", "settings.agentui.ai.toast.generated": "རྩ་ཤོག་བཟོ་ཡོདཔ — སྲུང་བཞག་མ་འབད་བའི་ཧེ་མར་ཞིབ་བཤེར་འབད", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "བོཊ་ཊོ་ཀེན (དགའ་གདམ་ — སྤྱི་ཡོངས་བོཊ་མཉམ་སྤྱོད་འབད་ནི་ལུ་སྟོངམ་བཞག)", "settings.agentui.field.telegramToken.hint": "འ་ཨེན་ཊི་འདི་ལུ་རང་གི་སྒོས་ཊེལེགིརམ་བོཊ་སྤྲོད་ནི་དོན་ལས་@BotFather་ལས་ཊོ་ཀེན་ཅིག་སྦྱར། སྟོངམ་བཞག་པ་ཅིན་སྒྲིག་སྟངས → མཐུད་ལམ་ནང་ཡོད་པའི་མཉམ་སྤྱོད་བོཊ་ཐོག་ལས་ འདེམས་བརྗོད་ཀྱི་སྔོན་ཚིག་བཀོལ་ཏེ་འབྱོར་ཚུགས།", + "settings.agentui.field.whatsapp": "WhatsApp ནང་ལན་གནང་", + "settings.agentui.field.whatsapp.hint": "ཁྲིམས་མཐུན་མེད་པའི་ WhatsApp API (waconector བརྒྱུད) ལག་ལེན་འཐབ — ཞབས་ཏོག་སྤྲོད་མི་ཅིག་འདེམས་ཞིནམ་ མཐུད་གནས་ཀྱི་ཞིབ་ཕྲ་བཀང་།", + "settings.agentui.field.whatsapp.webhookUrl": "ཝེབ་ཧུཀ་ ཡུ་ཨར་ཨེལ — ཞབས་ཏོག་སྤྲོད་མིའི་ཌེཤ་བོརཌ་ནང་སྦྱར", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "ཞབས་ཏོག་སྤྲོད་མིའི་ཁར་སྒྲིག་འབད་དགོཔའི་ཝེབ་ཧུཀ་ ཡུ་ཨར་ཨེལ་སྲུང་བཞག་འབད་བའི་ཤུལ་ལས་འདི་ནང་སྟོན་ཡི།", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/el.ts b/packages/app/src/i18n/el.ts index bbf807d4b3e4..16dd71aafeb8 100644 --- a/packages/app/src/i18n/el.ts +++ b/packages/app/src/i18n/el.ts @@ -841,6 +841,7 @@ export const dict = { "common.dismiss": "Παράβλεψη", "common.moreCountSuffix": " (+{{count}} περισσότερα)", "common.requestFailed": "Το αίτημα απέτυχε", + "common.optional": "προαιρετικό", "common.moreOptions": "Περισσότερες επιλογές", "common.learnMore": "Μάθετε περισσότερα", "common.rename": "Μετονομασία", @@ -1461,6 +1462,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Ανοίξτε αυτή τη σελίδα από συνδεδεμένο έργο για να δώσετε σε αυτόν τον πράκτορα το δικό του bot Telegram.", + "settings.agentui.error.whatsappIncomplete": "Ανοίξτε αυτή τη σελίδα από συνδεδεμένο έργο και συμπληρώστε όλα τα υποχρεωτικά πεδία για τον επιλεγμένο πάροχο WhatsApp.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1470,12 +1472,53 @@ export const dict = { "settings.agentui.ai.generate": "Δημιουργία", "settings.agentui.ai.generating": "Δημιουργείται…", "settings.agentui.ai.toast.generated": "Το προσχέδιο δημιουργήθηκε — ελέγξτε το πριν την αποθήκευση", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token bot (προαιρετικό — αφήστε κενό για κοινή χρήση του καθολικού bot)", "settings.agentui.field.telegramToken.hint": "Επικολλήστε ένα token από το @BotFather για να δώσετε σε αυτόν τον πράκτορα το δικό του αποκλειστικό bot Telegram. Αφήστε κενό για πρόσβαση μέσω του κοινού bot στις Ρυθμίσεις → Ενσωματώσεις, χρησιμοποιώντας το πρόθεμα εντολής του.", + "settings.agentui.field.whatsapp": "Απάντηση στο WhatsApp", + "settings.agentui.field.whatsapp.hint": "Χρησιμοποιεί ένα ανεπίσημο API WhatsApp (μέσω waconector) — επιλέξτε πάροχο και συμπληρώστε τα στοιχεία σύνδεσης. Οι αυτοφιλοξενούμενοι πάροχοι χρειάζονται τον δικό τους διακομιστή/container να τρέχει ξεχωριστά· αυτό απλώς συνδέεται μαζί του.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhook — επικολλήστε το στον πίνακα του παρόχου", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Το URL webhook προς ρύθμιση στον πάροχο εμφανίζεται εδώ μετά την αποθήκευση.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/en.ts b/packages/app/src/i18n/en.ts index adbb0802b7f6..76160b651bbc 100644 --- a/packages/app/src/i18n/en.ts +++ b/packages/app/src/i18n/en.ts @@ -883,6 +883,7 @@ export const dict = { "common.dismiss": "Dismiss", "common.moreCountSuffix": " (+{{count}} more)", "common.requestFailed": "Request failed", + "common.optional": "optional", "common.moreOptions": "More options", "common.learnMore": "Learn more", "common.rename": "Rename", @@ -940,6 +941,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", "settings.agentui.error.telegramNeedsProject": "Open this page from a connected project to give this agent its own Telegram bot.", + "settings.agentui.error.whatsappIncomplete": "Open this page from a connected project and fill in every required field for the selected WhatsApp provider.", "settings.agentui.toast.saved": "Agent saved", "settings.agentui.dialog.addTitle": "Create agent", "settings.agentui.dialog.editTitle": "Edit agent", @@ -949,12 +951,53 @@ export const dict = { "settings.agentui.ai.generate": "Generate", "settings.agentui.ai.generating": "Generating…", "settings.agentui.ai.toast.generated": "Draft generated — review before saving", + "settings.agentui.tabs.general": "General", + "settings.agentui.tabs.channels": "Channels", + "settings.agentui.tabs.tools": "Tools", + "settings.agentui.tabs.knowledge": "Knowledge", + "settings.agentui.tabs.audit": "Audit", + "settings.agentui.audit.title": "Message log", + "settings.agentui.audit.refresh": "Refresh", + "settings.agentui.audit.loading": "Loading…", + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", + "settings.agentui.audit.empty": "No messages logged yet.", + "settings.agentui.audit.blocked": "Blocked", + "settings.agentui.audit.incoming": "Received", + "settings.agentui.audit.outgoing": "Replied", + "settings.agentui.field.mcpServers": "MCP servers", + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", "settings.agentui.field.name": "Name", "settings.agentui.field.personality": "Personality", "settings.agentui.field.model": "Model", "settings.agentui.field.telegram": "Reply on Telegram", "settings.agentui.field.telegramToken.placeholder": "Bot token (optional — leave empty to share the global bot)", "settings.agentui.field.telegramToken.hint": "Paste a token from @BotFather to give this agent its own dedicated Telegram bot. Leave empty to reach it through the shared bot in Settings → Integrations instead, using its command trigger.", + "settings.agentui.field.whatsapp": "Reply on WhatsApp", + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", + "settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", + "settings.agentui.field.whatsapp.hint": "Uses an unofficial WhatsApp API (via waconector) — pick a provider and fill in its connection details. Self-hosted providers (WAHA, Evolution GO, Wuzapi, QuePasa, WPPConnect) need their own server/container running separately; this only connects to it.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — paste this into the provider's dashboard", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", + "settings.agentui.field.whatsapp.webhookAfterSave": "The webhook URL to configure on the provider's side appears here after you save.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", "settings.agentui.field.guardrails": "Guardrails", "settings.agentui.field.guardrailsLevel": "Guardrails level", diff --git a/packages/app/src/i18n/es.ts b/packages/app/src/i18n/es.ts index 15ad2def9d29..5709348607b9 100644 --- a/packages/app/src/i18n/es.ts +++ b/packages/app/src/i18n/es.ts @@ -870,6 +870,7 @@ export const dict = { "common.closeTab": "Cerrar pestaña", "common.dismiss": "Descartar", "common.requestFailed": "Solicitud fallida", + "common.optional": "opcional", "common.moreOptions": "Más opciones", "common.learnMore": "Más información", "common.rename": "Renombrar", @@ -1553,6 +1554,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Abre esta página desde un proyecto conectado para darle a este agente su propio bot de Telegram.", + "settings.agentui.error.whatsappIncomplete": "Abre esta página desde un proyecto conectado y completa todos los campos obligatorios del proveedor de WhatsApp seleccionado.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1562,12 +1564,53 @@ export const dict = { "settings.agentui.ai.generate": "Generar", "settings.agentui.ai.generating": "Generando…", "settings.agentui.ai.toast.generated": "Borrador generado — revísalo antes de guardar", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token del bot (opcional — déjalo vacío para compartir el bot global)", "settings.agentui.field.telegramToken.hint": "Pega un token de @BotFather para darle a este agente su propio bot dedicado de Telegram. Déjalo vacío para acceder a través del bot compartido en Configuración → Integraciones, usando su prefijo de comando.", + "settings.agentui.field.whatsapp": "Responder en WhatsApp", + "settings.agentui.field.whatsapp.hint": "Usa una API no oficial de WhatsApp (vía waconector) — elige un proveedor y completa los datos de conexión. Los proveedores autoalojados necesitan su propio servidor/contenedor ejecutándose por separado; esto solo se conecta a él.", + "settings.agentui.field.whatsapp.webhookUrl": "URL del webhook — pégala en el panel del proveedor", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "La URL del webhook a configurar en el proveedor aparece aquí después de guardar.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/et.ts b/packages/app/src/i18n/et.ts index ce0fd8f610d6..edae682e1528 100644 --- a/packages/app/src/i18n/et.ts +++ b/packages/app/src/i18n/et.ts @@ -828,6 +828,7 @@ export const dict = { "common.dismiss": "Loobu", "common.moreCountSuffix": " (+{{count}} veel)", "common.requestFailed": "Taotlus ebaõnnestus", + "common.optional": "valikuline", "common.moreOptions": "Rohkem valikuid", "common.learnMore": "Lisateavet", "common.rename": "Nimeta ümber", @@ -1439,6 +1440,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Ava see leht ühendatud projektist, et anda sellele agendile oma Telegrami bot.", + "settings.agentui.error.whatsappIncomplete": "Ava see leht ühendatud projektist ja täida kõik valitud WhatsAppi teenusepakkuja kohustuslikud väljad.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1448,12 +1450,53 @@ export const dict = { "settings.agentui.ai.generate": "Genereeri", "settings.agentui.ai.generating": "Genereerimine…", "settings.agentui.ai.toast.generated": "Mustand loodud — vaata üle enne salvestamist", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Boti token (valikuline — jäta tühjaks globaalse boti jagamiseks)", "settings.agentui.field.telegramToken.hint": "Kleebi @BotFatherilt saadud token, et anda sellele agendile oma pühendatud Telegrami bot. Jäta tühjaks, et kasutada jagatud botti Seaded → Integratsioonid, kasutades selle käsueesliidet.", + "settings.agentui.field.whatsapp": "Vasta WhatsAppis", + "settings.agentui.field.whatsapp.hint": "Kasutab mitteametlikku WhatsAppi API-t (waconectori kaudu) — vali teenusepakkuja ja täida ühenduse andmed. Ise majutatavad teenusepakkujad vajavad oma eraldi töötavat serverit/konteinerit; see ainult ühendub sellega.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhooki URL — kleebi see teenusepakkuja armatuurlauale", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Teenusepakkuja juures seadistatav webhooki URL kuvatakse siin pärast salvestamist.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/fa.ts b/packages/app/src/i18n/fa.ts index 1098352a9233..13a0a8b2655c 100644 --- a/packages/app/src/i18n/fa.ts +++ b/packages/app/src/i18n/fa.ts @@ -831,6 +831,7 @@ export const dict = { "common.dismiss": "رد کردن", "common.moreCountSuffix": " (+ {{count}} بیشتر)", "common.requestFailed": "درخواست ناموفق بود", + "common.optional": "اختیاری", "common.moreOptions": "گزینه های بیشتر", "common.learnMore": "بیشتر بدانید", "common.rename": "تغییر نام دهید", @@ -1443,6 +1444,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "این صفحه را از یک پروژه متصل باز کنید تا به این عامل ربات تلگرام اختصاصی خود را بدهید.", + "settings.agentui.error.whatsappIncomplete": "این صفحه را از یک پروژه متصل باز کنید و همه فیلدهای ضروری برای ارائه‌دهنده واتس‌اپ انتخابی را پر کنید.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1452,12 +1454,53 @@ export const dict = { "settings.agentui.ai.generate": "ایجاد کن", "settings.agentui.ai.generating": "در حال ایجاد…", "settings.agentui.ai.toast.generated": "پیش‌نویس ایجاد شد — پیش از ذخیره بازبینی کنید", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "توکن ربات (اختیاری — برای اشتراک‌گذاری ربات سراسری خالی بگذارید)", "settings.agentui.field.telegramToken.hint": "یک توکن از @BotFather بچسبانید تا به این عامل ربات تلگرام اختصاصی خودش را بدهید. برای دسترسی از طریق ربات مشترک در تنظیمات ← یکپارچه‌سازی‌ها، با پیشوند دستور آن، خالی بگذارید.", + "settings.agentui.field.whatsapp": "پاسخ در واتس‌اپ", + "settings.agentui.field.whatsapp.hint": "از یک API غیررسمی واتس‌اپ استفاده می‌کند (از طریق waconector) — یک ارائه‌دهنده انتخاب کنید و جزئیات اتصال را پر کنید. ارائه‌دهندگان خودمیزبان به سرور/کانتینر جداگانه خود نیاز دارند؛ این فقط به آن متصل می‌شود.", + "settings.agentui.field.whatsapp.webhookUrl": "آدرس webhook — آن را در داشبورد ارائه‌دهنده جای‌گذاری کنید", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "آدرس webhook که باید در سمت ارائه‌دهنده تنظیم شود، پس از ذخیره در اینجا نمایش داده می‌شود.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/fi.ts b/packages/app/src/i18n/fi.ts index 5f3c67ecb458..71f8a5c709a7 100644 --- a/packages/app/src/i18n/fi.ts +++ b/packages/app/src/i18n/fi.ts @@ -731,6 +731,7 @@ export const dict = { "common.dismiss": "Hylkää", "common.moreCountSuffix": " (+{{count}} muuta)", "common.requestFailed": "Pyyntö epäonnistui", + "common.optional": "valinnainen", "common.moreOptions": "Lisää vaihtoehtoja", "common.learnMore": "Lue lisää", "common.rename": "Nimeä uudelleen", @@ -1456,6 +1457,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Avaa tämä sivu yhdistetystä projektista antaaksesi tälle agentille oman Telegram-botin.", + "settings.agentui.error.whatsappIncomplete": "Avaa tämä sivu yhdistetystä projektista ja täytä kaikki valitun WhatsApp-palveluntarjoajan pakolliset kentät.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1465,12 +1467,53 @@ export const dict = { "settings.agentui.ai.generate": "Luo", "settings.agentui.ai.generating": "Luodaan…", "settings.agentui.ai.toast.generated": "Luonnos luotu — tarkista ennen tallennusta", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Botin token (valinnainen — jätä tyhjäksi jakaaksesi globaalin botin)", "settings.agentui.field.telegramToken.hint": "Liitä token @BotFatherilta antaaksesi tälle agentille oman omistetun Telegram-botin. Jätä tyhjäksi käyttääksesi jaettua bottia kohdassa Asetukset → Integraatiot, sen komentoetuliitteellä.", + "settings.agentui.field.whatsapp": "Vastaa WhatsAppissa", + "settings.agentui.field.whatsapp.hint": "Käyttää epävirallista WhatsApp-rajapintaa (waconectorin kautta) — valitse palveluntarjoaja ja täytä yhteystiedot. Itse isännöidyt palveluntarjoajat tarvitsevat oman erikseen käynnissä olevan palvelimen/säiliön; tämä vain yhdistää siihen.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook-URL — liitä se palveluntarjoajan hallintapaneeliin", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Palveluntarjoajalle määritettävä webhook-URL näkyy tässä tallennuksen jälkeen.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/fo.ts b/packages/app/src/i18n/fo.ts index 590f1e26c021..7ced919f5dab 100644 --- a/packages/app/src/i18n/fo.ts +++ b/packages/app/src/i18n/fo.ts @@ -832,6 +832,7 @@ export const dict = { "common.dismiss": "Loysa úr starvi", "common.moreCountSuffix": " (+{{count}} fleiri)", "common.requestFailed": "Umbønin miseydnaðist", + "common.optional": "valfrítt", "common.moreOptions": "Fleiri møguleikar", "common.learnMore": "Lær meira", "common.rename": "Umnevna", @@ -1442,6 +1443,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Opna hesa síðuna frá einum tengdum verkætlan fyri at geva hesum umboðsmanni sín egna Telegram bot.", + "settings.agentui.error.whatsappIncomplete": "Opna hesa síðuna frá einum tengdum verkætlan og fyll út allar neyðugar felti fyri valdan WhatsApp veitara.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1451,12 +1453,53 @@ export const dict = { "settings.agentui.ai.generate": "Ger", "settings.agentui.ai.generating": "Ger…", "settings.agentui.ai.toast.generated": "Uppskot gjørt — eftirsí áðrenn goymt verður", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot token (valfrítt — lat tómt fyri at deila globala botin)", "settings.agentui.field.telegramToken.hint": "Set inn token frá @BotFather fyri at geva hesum umboðsmanni sín egna serligan Telegram bot. Lat tómt fyri at náa hann gjøgnum deildan botin í Stillingar → Sameiningar, við hansara boð-forstavi.", + "settings.agentui.field.whatsapp": "Svara á WhatsApp", + "settings.agentui.field.whatsapp.hint": "Brúkar ein óformligan WhatsApp API (um waconector) — vel ein veitara og fyll út sambandsupplýsingar. Sjálvhýstir veitarar krevja sín egnan ambátt/container koyrandi sundurskild; hetta bert tengir til hann.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — set hana inn í veitarans mannaborð", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Webhook URL'in, sum skal setast upp hjá veitaranum, sæst her aftaná goymt verður.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/fr.ts b/packages/app/src/i18n/fr.ts index 98131ab1ccea..ae3304b310bd 100644 --- a/packages/app/src/i18n/fr.ts +++ b/packages/app/src/i18n/fr.ts @@ -808,6 +808,7 @@ export const dict = { "common.closeTab": "Fermer l'onglet", "common.dismiss": "Ignorer", "common.requestFailed": "La demande a échoué", + "common.optional": "facultatif", "common.moreOptions": "Plus d'options", "common.learnMore": "En savoir plus", "common.rename": "Renommer", @@ -1487,6 +1488,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Ouvrez cette page depuis un projet connecté pour donner à cet agent son propre bot Telegram.", + "settings.agentui.error.whatsappIncomplete": "Ouvrez cette page depuis un projet connecté et remplissez tous les champs requis pour le fournisseur WhatsApp sélectionné.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1496,12 +1498,53 @@ export const dict = { "settings.agentui.ai.generate": "Générer", "settings.agentui.ai.generating": "Génération…", "settings.agentui.ai.toast.generated": "Brouillon généré — vérifiez avant d'enregistrer", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Jeton du bot (facultatif — laissez vide pour partager le bot global)", "settings.agentui.field.telegramToken.hint": "Collez un jeton de @BotFather pour donner à cet agent son propre bot Telegram dédié. Laissez vide pour y accéder via le bot partagé dans Paramètres → Intégrations, avec son préfixe de commande.", + "settings.agentui.field.whatsapp": "Répondre sur WhatsApp", + "settings.agentui.field.whatsapp.hint": "Utilise une API WhatsApp non officielle (via waconector) — choisissez un fournisseur et remplissez les informations de connexion. Les fournisseurs auto-hébergés nécessitent leur propre serveur/conteneur exécuté séparément ; ceci ne fait que s'y connecter.", + "settings.agentui.field.whatsapp.webhookUrl": "URL du webhook — collez-la dans le tableau de bord du fournisseur", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "L'URL du webhook à configurer chez le fournisseur apparaît ici après l'enregistrement.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/hi.ts b/packages/app/src/i18n/hi.ts index 711bc88be348..524d1fcc474e 100644 --- a/packages/app/src/i18n/hi.ts +++ b/packages/app/src/i18n/hi.ts @@ -842,6 +842,7 @@ export const dict = { "common.dismiss": "हटाएँ", "common.moreCountSuffix": " (+{{count}} और)", "common.requestFailed": "अनुरोध विफल रहा", + "common.optional": "वैकल्पिक", "common.moreOptions": "अधिक विकल्प", "common.learnMore": "और अधिक जानें", "common.rename": "नाम बदलें", @@ -1451,6 +1452,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "इस एजेंट को अपना खुद का टेलीग्राम बॉट देने के लिए एक कनेक्टेड प्रोजेक्ट से यह पेज खोलें।", + "settings.agentui.error.whatsappIncomplete": "इस पेज को किसी कनेक्टेड प्रोजेक्ट से खोलें और चयनित WhatsApp प्रदाता के लिए सभी आवश्यक फ़ील्ड भरें।", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1460,12 +1462,53 @@ export const dict = { "settings.agentui.ai.generate": "जनरेट करें", "settings.agentui.ai.generating": "जनरेट हो रहा है…", "settings.agentui.ai.toast.generated": "ड्राफ्ट जनरेट हुआ — सेव करने से पहले समीक्षा करें", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "बॉट टोकन (वैकल्पिक — ग्लोबल बॉट साझा करने के लिए खाली छोड़ें)", "settings.agentui.field.telegramToken.hint": "इस एजेंट को अपना समर्पित टेलीग्राम बॉट देने के लिए @BotFather से टोकन पेस्ट करें। सेटिंग्स → इंटीग्रेशन में साझा बॉट के माध्यम से, उसके कमांड ट्रिगर का उपयोग करके पहुंचने के लिए खाली छोड़ें।", + "settings.agentui.field.whatsapp": "WhatsApp पर उत्तर दें", + "settings.agentui.field.whatsapp.hint": "एक गैर-आधिकारिक WhatsApp API का उपयोग करता है (waconector के माध्यम से) — एक प्रदाता चुनें और कनेक्शन विवरण भरें। स्व-होस्टेड प्रदाताओं को अपना खुद का सर्वर/कंटेनर अलग से चलाने की आवश्यकता होती है; यह केवल उससे जुड़ता है।", + "settings.agentui.field.whatsapp.webhookUrl": "वेबहुक URL — इसे प्रदाता के डैशबोर्ड में पेस्ट करें", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "प्रदाता की ओर से कॉन्फ़िगर करने के लिए वेबहुक URL सेव करने के बाद यहां दिखाई देता है।", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/hr.ts b/packages/app/src/i18n/hr.ts index 18d6674b577a..84e179cfafd9 100644 --- a/packages/app/src/i18n/hr.ts +++ b/packages/app/src/i18n/hr.ts @@ -841,6 +841,7 @@ export const dict = { "common.dismiss": "Odbaciti", "common.moreCountSuffix": "(još još {{count}})", "common.requestFailed": "Zahtjev nije uspio", + "common.optional": "neobavezno", "common.moreOptions": "Više opcija", "common.learnMore": "Saznajte više", "common.rename": "Preimenovati", @@ -1456,6 +1457,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Otvorite ovu stranicu iz povezanog projekta kako biste ovom agentu dali vlastiti Telegram bot.", + "settings.agentui.error.whatsappIncomplete": "Otvorite ovu stranicu iz povezanog projekta i ispunite sva obavezna polja za odabranog WhatsApp pružatelja.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1465,12 +1467,53 @@ export const dict = { "settings.agentui.ai.generate": "Generiraj", "settings.agentui.ai.generating": "Generiranje…", "settings.agentui.ai.toast.generated": "Nacrt je generiran — pregledajte prije spremanja", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token bota (neobavezno — ostavite prazno za dijeljenje globalnog bota)", "settings.agentui.field.telegramToken.hint": "Zalijepite token od @BotFather kako biste ovom agentu dali vlastiti namjenski Telegram bot. Ostavite prazno za pristup putem zajedničkog bota u Postavke → Integracije, koristeći njegov prefiks naredbe.", + "settings.agentui.field.whatsapp": "Odgovori na WhatsAppu", + "settings.agentui.field.whatsapp.hint": "Koristi neslužbeni WhatsApp API (putem waconector) — odaberite pružatelja i ispunite podatke o vezi. Samostalno hostirani pružatelji trebaju vlastiti poslužitelj/spremnik koji radi zasebno; ovo se samo povezuje s njim.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhooka — zalijepite ga na nadzornu ploču pružatelja", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL webhooka za konfiguraciju kod pružatelja pojavljuje se ovdje nakon spremanja.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/hu.ts b/packages/app/src/i18n/hu.ts index 1b1c54c3a6b6..6d1bad4df370 100644 --- a/packages/app/src/i18n/hu.ts +++ b/packages/app/src/i18n/hu.ts @@ -839,6 +839,7 @@ export const dict = { "common.dismiss": "Elvetés", "common.moreCountSuffix": "(+{{count}} további)", "common.requestFailed": "A kérés sikertelen", + "common.optional": "opcionális", "common.moreOptions": "További lehetőségek", "common.learnMore": "További információ", "common.rename": "Átnevezés", @@ -1458,6 +1459,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Nyisd meg ezt az oldalt egy csatlakoztatott projektből, hogy saját Telegram botot adj ennek az ügynöknek.", + "settings.agentui.error.whatsappIncomplete": "Nyisd meg ezt az oldalt egy csatlakoztatott projektből, és töltsd ki a kiválasztott WhatsApp szolgáltató minden kötelező mezőjét.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1467,12 +1469,53 @@ export const dict = { "settings.agentui.ai.generate": "Generálás", "settings.agentui.ai.generating": "Generálás…", "settings.agentui.ai.toast.generated": "Piszkozat elkészült — mentés előtt tekintsd át", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot token (opcionális — hagyd üresen a globális bot megosztásához)", "settings.agentui.field.telegramToken.hint": "Illessz be egy tokent a @BotFathertől, hogy saját dedikált Telegram botot adj ennek az ügynöknek. Hagyd üresen, hogy a Beállítások → Integrációk menüben lévő megosztott boton keresztül legyen elérhető, a parancs-előtagjával.", + "settings.agentui.field.whatsapp": "Válasz WhatsAppon", + "settings.agentui.field.whatsapp.hint": "Nem hivatalos WhatsApp API-t használ (a waconectoron keresztül) — válassz szolgáltatót, és töltsd ki a kapcsolati adatokat. Az önállóan üzemeltetett szolgáltatókhoz saját, külön futó szerver/konténer szükséges; ez csak csatlakozik hozzá.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — illeszd be a szolgáltató irányítópultjába", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "A szolgáltatónál beállítandó webhook URL mentés után itt jelenik meg.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/hy.ts b/packages/app/src/i18n/hy.ts index 486a7eba3c75..f23e16590b4b 100644 --- a/packages/app/src/i18n/hy.ts +++ b/packages/app/src/i18n/hy.ts @@ -838,6 +838,7 @@ export const dict = { "common.dismiss": "Փակել", "common.moreCountSuffix": " (+{{count}} ավելին)", "common.requestFailed": "Հարցումը ձախողվեց", + "common.optional": "ընտրովի", "common.moreOptions": "Լրացուցիչ ընտրանքներ", "common.learnMore": "Իմանալ ավելին", "common.rename": "Վերանվանել", @@ -1453,6 +1454,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Բացեք այս էջը միացված նախագծից՝ այս գործակալին իր սեփական Telegram բոտը տալու համար։", + "settings.agentui.error.whatsappIncomplete": "Բացեք այս էջը միացված նախագծից և լրացրեք ընտրված WhatsApp մատակարարի բոլոր պարտադիր դաշտերը։", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1462,12 +1464,53 @@ export const dict = { "settings.agentui.ai.generate": "Ստեղծել", "settings.agentui.ai.generating": "Ստեղծվում է…", "settings.agentui.ai.toast.generated": "Սևագիրը ստեղծված է — վերանայեք պահպանելուց առաջ", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Բոտի թոքեն (ընտրովի — թողեք դատարկ՝ գլոբալ բոտը կիսելու համար)", "settings.agentui.field.telegramToken.hint": "Փակցրեք թոքեն @BotFather-ից՝ այս գործակալին իր սեփական հատուկ Telegram բոտը տալու համար։ Թողեք դատարկ՝ Կարգավորումներ → Ինտեգրումներում ընդհանուր բոտի միջոցով հասանելի լինելու համար՝ օգտագործելով դրա հրամանի նախածանցը։", + "settings.agentui.field.whatsapp": "Պատասխանել WhatsApp-ում", + "settings.agentui.field.whatsapp.hint": "Օգտագործում է ոչ պաշտոնական WhatsApp API (waconector-ի միջոցով) — ընտրեք մատակարար և լրացրեք կապի տվյալները։ Ինքնահյուրընկալվող մատակարարներին անհրաժեշտ է իրենց սեփական սերվերը/կոնտեյները առանձին աշխատեցնել.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — տեղադրեք մատակարարի վահանակում", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Մատակարարի կողմից կարգավորվող Webhook URL-ը հայտնվում է այստեղ պահպանելուց հետո։", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/id.ts b/packages/app/src/i18n/id.ts index 561baf42a133..e0d54bb6eef4 100644 --- a/packages/app/src/i18n/id.ts +++ b/packages/app/src/i18n/id.ts @@ -906,6 +906,7 @@ export const dict = { "common.dismiss": "Tutup", "common.moreCountSuffix": " (+{{count}} lainnya)", "common.requestFailed": "Permintaan gagal", + "common.optional": "opsional", "common.moreOptions": "Opsi lainnya", "common.learnMore": "Pelajari lebih lanjut", "common.rename": "Ganti nama", @@ -1538,6 +1539,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Buka halaman ini dari proyek yang terhubung untuk memberi agen ini bot Telegram-nya sendiri.", + "settings.agentui.error.whatsappIncomplete": "Buka halaman ini dari proyek yang terhubung dan isi semua kolom wajib untuk penyedia WhatsApp yang dipilih.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1547,12 +1549,53 @@ export const dict = { "settings.agentui.ai.generate": "Buat", "settings.agentui.ai.generating": "Membuat…", "settings.agentui.ai.toast.generated": "Draf dibuat — tinjau sebelum menyimpan", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token bot (opsional — biarkan kosong untuk berbagi bot global)", "settings.agentui.field.telegramToken.hint": "Tempel token dari @BotFather untuk memberi agen ini bot Telegram khusus miliknya sendiri. Biarkan kosong untuk mengaksesnya melalui bot bersama di Pengaturan → Integrasi, menggunakan prefiks perintahnya.", + "settings.agentui.field.whatsapp": "Balas di WhatsApp", + "settings.agentui.field.whatsapp.hint": "Menggunakan API WhatsApp tidak resmi (melalui waconector) — pilih penyedia dan isi detail koneksi. Penyedia self-hosted memerlukan server/kontainer sendiri yang berjalan terpisah; ini hanya terhubung ke sana.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhook — tempelkan ke dasbor penyedia", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL webhook yang perlu dikonfigurasi di sisi penyedia muncul di sini setelah Anda menyimpan.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/is.ts b/packages/app/src/i18n/is.ts index 64e2b519fe67..44b9852e9592 100644 --- a/packages/app/src/i18n/is.ts +++ b/packages/app/src/i18n/is.ts @@ -835,6 +835,7 @@ export const dict = { "common.dismiss": "Segja frá", "common.moreCountSuffix": "(+{{count}} meira)", "common.requestFailed": "Beiðni mistókst", + "common.optional": "valfrjálst", "common.moreOptions": "Fleiri valkostir", "common.learnMore": "Lærðu meira", "common.rename": "Endurnefna", @@ -1445,6 +1446,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Opnaðu þessa síðu úr tengdu verkefni til að gefa þessum umboðsmanni sinn eigin Telegram bot.", + "settings.agentui.error.whatsappIncomplete": "Opnaðu þessa síðu úr tengdu verkefni og fylltu út öll nauðsynleg svæði fyrir valinn WhatsApp veitanda.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1454,12 +1456,53 @@ export const dict = { "settings.agentui.ai.generate": "Búa til", "settings.agentui.ai.generating": "Bý til…", "settings.agentui.ai.toast.generated": "Uppkast búið til — yfirfarðu áður en þú vistar", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot token (valfrjálst — skildu eftir autt til að deila alheims botnum)", "settings.agentui.field.telegramToken.hint": "Límdu token frá @BotFather til að gefa þessum umboðsmanni sinn eigin sérstakan Telegram bot. Skildu eftir autt til að nálgast hann í gegnum sameiginlega botinn í Stillingar → Samþættingar, með skipanaforskeyti hans.", + "settings.agentui.field.whatsapp": "Svara á WhatsApp", + "settings.agentui.field.whatsapp.hint": "Notar óopinbert WhatsApp API (í gegnum waconector) — veldu veitanda og fylltu út tengingarupplýsingar. Sjálfhýstir veitendur þurfa eigin netþjón/gám sem keyrir sérstaklega; þetta tengist bara við hann.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook slóð — límdu hana inn í mælaborð veitanda", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Webhook slóðin sem stilla þarf hjá veitanda birtist hér eftir að þú vistar.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/it.ts b/packages/app/src/i18n/it.ts index 18a5919506db..2930f7101f2f 100644 --- a/packages/app/src/i18n/it.ts +++ b/packages/app/src/i18n/it.ts @@ -752,6 +752,7 @@ export const dict = { "common.dismiss": "Ignora", "common.moreCountSuffix": " (+ altri {{count}})", "common.requestFailed": "Richiesta non riuscita", + "common.optional": "facoltativo", "common.moreOptions": "Altre opzioni", "common.learnMore": "Saperne di più", "common.rename": "Rinomina", @@ -1464,6 +1465,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Apri questa pagina da un progetto connesso per dare a questo agente il proprio bot Telegram.", + "settings.agentui.error.whatsappIncomplete": "Apri questa pagina da un progetto connesso e compila tutti i campi obbligatori per il provider WhatsApp selezionato.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1473,12 +1475,53 @@ export const dict = { "settings.agentui.ai.generate": "Genera", "settings.agentui.ai.generating": "Generazione…", "settings.agentui.ai.toast.generated": "Bozza generata — rivedila prima di salvare", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token del bot (facoltativo — lascia vuoto per condividere il bot globale)", "settings.agentui.field.telegramToken.hint": "Incolla un token da @BotFather per dare a questo agente il proprio bot Telegram dedicato. Lascia vuoto per raggiungerlo tramite il bot condiviso in Impostazioni → Integrazioni, usando il suo prefisso comando.", + "settings.agentui.field.whatsapp": "Rispondi su WhatsApp", + "settings.agentui.field.whatsapp.hint": "Usa un'API WhatsApp non ufficiale (tramite waconector) — scegli un provider e compila i dati di connessione. I provider self-hosted richiedono un proprio server/container in esecuzione separata; questo si limita a connettersi.", + "settings.agentui.field.whatsapp.webhookUrl": "URL del webhook — incollalo nella dashboard del provider", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "L'URL del webhook da configurare presso il provider appare qui dopo il salvataggio.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/ja.ts b/packages/app/src/i18n/ja.ts index 97577bfba125..ae8d286539e7 100644 --- a/packages/app/src/i18n/ja.ts +++ b/packages/app/src/i18n/ja.ts @@ -790,6 +790,7 @@ export const dict = { "common.closeTab": "タブを閉じる", "common.dismiss": "閉じる", "common.requestFailed": "リクエストに失敗しました", + "common.optional": "任意", "common.moreOptions": "その他のオプション", "common.learnMore": "詳細", "common.rename": "名前を変更", @@ -1457,6 +1458,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "このエージェント専用のTelegramボットを設定するには、接続済みのプロジェクトからこのページを開いてください。", + "settings.agentui.error.whatsappIncomplete": "接続済みのプロジェクトからこのページを開き、選択したWhatsAppプロバイダーの必須項目をすべて入力してください。", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1466,12 +1468,53 @@ export const dict = { "settings.agentui.ai.generate": "生成", "settings.agentui.ai.generating": "生成中…", "settings.agentui.ai.toast.generated": "下書きを生成しました — 保存前に確認してください", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "ボットトークン(任意 — グローバルボットを共有する場合は空欄のまま)", "settings.agentui.field.telegramToken.hint": "@BotFatherのトークンを貼り付けると、このエージェント専用のTelegramボットになります。空欄のままにすると、設定 → 連携にある共有ボットを、そのコマンドトリガー経由で利用します。", + "settings.agentui.field.whatsapp": "WhatsAppで返信", + "settings.agentui.field.whatsapp.hint": "非公式のWhatsApp API(waconector経由)を使用します — プロバイダーを選び、接続情報を入力してください。セルフホスト型プロバイダーは別途稼働する独自サーバー/コンテナが必要です。これはそこに接続するだけです。", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — プロバイダーのダッシュボードに貼り付けてください", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "プロバイダー側で設定するWebhook URLは、保存後にここに表示されます。", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/ka.ts b/packages/app/src/i18n/ka.ts index 870b1fa1e5b8..e0953132641d 100644 --- a/packages/app/src/i18n/ka.ts +++ b/packages/app/src/i18n/ka.ts @@ -831,6 +831,7 @@ export const dict = { "common.dismiss": "დატოვება", "common.moreCountSuffix": " (+{{count}} მეტი)", "common.requestFailed": "მოთხოვნა ვერ მოხერხდა", + "common.optional": "არასავალდებულო", "common.moreOptions": "მეტი პარამეტრები", "common.learnMore": "შეიტყვეთ მეტი", "common.rename": "გადარქმევა", @@ -1444,6 +1445,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "ამ აგენტს საკუთარი Telegram ბოტის მისანიჭებლად გახსენით ეს გვერდი დაკავშირებული პროექტიდან.", + "settings.agentui.error.whatsappIncomplete": "გახსენით ეს გვერდი დაკავშირებული პროექტიდან და შეავსეთ ყველა საჭირო ველი არჩეული WhatsApp პროვაიდერისთვის.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1453,12 +1455,53 @@ export const dict = { "settings.agentui.ai.generate": "გენერირება", "settings.agentui.ai.generating": "გენერირდება…", "settings.agentui.ai.toast.generated": "დრაფტი შეიქმნა — შენახვამდე გადახედეთ", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "ბოტის ტოკენი (არასავალდებულო — დატოვეთ ცარიელი გლობალური ბოტის გასაზიარებლად)", "settings.agentui.field.telegramToken.hint": "ჩასვით ტოკენი @BotFather-იდან, რომ ამ აგენტს მისცეთ საკუთარი ტელეგრამის ბოტი. დატოვეთ ცარიელი, რომ წვდომა მოხდეს პარამეტრები → ინტეგრაციები-ში არსებული საერთო ბოტის მეშვეობით, მისი ბრძანების პრეფიქსით.", + "settings.agentui.field.whatsapp": "პასუხი WhatsApp-ზე", + "settings.agentui.field.whatsapp.hint": "იყენებს არაოფიციალურ WhatsApp API-ს (waconector-ის მეშვეობით) — აირჩიეთ პროვაიდერი და შეავსეთ კავშირის დეტალები. თვით-ჰოსტინგის პროვაიდერებს სჭირდებათ საკუთარი სერვერი/კონტეინერი ცალკე გაშვებული.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — ჩასვით პროვაიდერის დაშბორდში", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "პროვაიდერთან დასაკონფიგურირებელი Webhook URL აქ გამოჩნდება შენახვის შემდეგ.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/km.ts b/packages/app/src/i18n/km.ts index 7c8d48ad3a52..125282ceaf74 100644 --- a/packages/app/src/i18n/km.ts +++ b/packages/app/src/i18n/km.ts @@ -829,6 +829,7 @@ export const dict = { "common.dismiss": "ច្រានចោល", "common.moreCountSuffix": "(+{{count}} ច្រើនទៀត)", "common.requestFailed": "សំណើបានបរាជ័យ", + "common.optional": "ស្រេចចិត្ត", "common.moreOptions": "ជម្រើសច្រើនទៀត", "common.learnMore": "ស្វែងយល់បន្ថែម", "common.rename": "ប្តូរឈ្មោះ", @@ -1439,6 +1440,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "បើកទំព័រនេះពីគម្រោងដែលបានភ្ជាប់ ដើម្បីផ្តល់ឱ្យភ្នាក់ងារនេះនូវរូបយន្ត Telegram ផ្ទាល់ខ្លួន។", + "settings.agentui.error.whatsappIncomplete": "បើកទំព័រនេះពីគម្រោងដែលបានភ្ជាប់ ហើយបំពេញគ្រប់វាលដែលត្រូវការសម្រាប់អ្នកផ្តល់សេវា WhatsApp ដែលបានជ្រើសរើស។", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1448,12 +1450,53 @@ export const dict = { "settings.agentui.ai.generate": "បង្កើត", "settings.agentui.ai.generating": "កំពុងបង្កើត…", "settings.agentui.ai.toast.generated": "ព្រាងត្រូវបានបង្កើត — សូមពិនិត្យមុននឹងរក្សាទុក", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "តូខឹនរូបយន្ត (ស្រេចចិត្ត — ទុកទទេដើម្បីចែករំលែករូបយន្តសកល)", "settings.agentui.field.telegramToken.hint": "បិទភ្ជាប់តូខឹនពី @BotFather ដើម្បីផ្តល់ឱ្យភ្នាក់ងារនេះនូវរូបយន្ត Telegram ជាក់លាក់របស់ខ្លួន។ ទុកទទេដើម្បីចូលប្រើតាមរយៈរូបយន្តរួមនៅក្នុងការកំណត់ → ការរួមបញ្ចូល ដោយប្រើបុព្វបទពាក្យបញ្ជារបស់វា។", + "settings.agentui.field.whatsapp": "ឆ្លើយតបនៅលើ WhatsApp", + "settings.agentui.field.whatsapp.hint": "ប្រើ API WhatsApp មិនផ្លូវការ (តាមរយៈ waconector) — ជ្រើសរើសអ្នកផ្តល់សេវា ហើយបំពេញព័ត៌មានលម្អិតការតភ្ជាប់។ អ្នកផ្តល់សេវាដែលបង្ហោះដោយខ្លួនឯងត្រូវការម៉ាស៊ីនមេ/កុងតឺន័រផ្ទាល់ខ្លួនរបស់ពួកគេដំណើរការដាច់ដោយឡែក។", + "settings.agentui.field.whatsapp.webhookUrl": "URL Webhook — បិទភ្ជាប់វានៅក្នុងផ្ទាំងគ្រប់គ្រងរបស់អ្នកផ្តល់សេវា", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL Webhook ដែលត្រូវកំណត់រចនាសម្ព័ន្ធនៅខាងអ្នកផ្តល់សេវានឹងបង្ហាញនៅទីនេះបន្ទាប់ពីអ្នករក្សាទុក។", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/ko.ts b/packages/app/src/i18n/ko.ts index 64beb946c3df..1968a10a084a 100644 --- a/packages/app/src/i18n/ko.ts +++ b/packages/app/src/i18n/ko.ts @@ -553,6 +553,7 @@ export const dict = { "common.closeTab": "탭 닫기", "common.dismiss": "닫기", "common.requestFailed": "요청 실패", + "common.optional": "선택 사항", "common.moreOptions": "더 많은 옵션", "common.learnMore": "더 알아보기", "common.rename": "이름 바꾸기", @@ -1455,6 +1456,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "이 에이전트에 전용 텔레그램 봇을 부여하려면 연결된 프로젝트에서 이 페이지를 여세요.", + "settings.agentui.error.whatsappIncomplete": "연결된 프로젝트에서 이 페이지를 열고 선택한 WhatsApp 제공업체의 모든 필수 필드를 입력하세요.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1464,12 +1466,53 @@ export const dict = { "settings.agentui.ai.generate": "생성", "settings.agentui.ai.generating": "생성 중…", "settings.agentui.ai.toast.generated": "초안이 생성되었습니다 — 저장 전에 검토하세요", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "봇 토큰(선택 사항 — 글로벌 봇을 공유하려면 비워 두세요)", "settings.agentui.field.telegramToken.hint": "이 에이전트에 전용 텔레그램 봇을 부여하려면 @BotFather의 토큰을 붙여넣으세요. 비워 두면 설정 → 통합에 있는 공유 봇을 명령 트리거를 통해 대신 사용합니다.", + "settings.agentui.field.whatsapp": "WhatsApp에서 응답", + "settings.agentui.field.whatsapp.hint": "비공식 WhatsApp API를 사용합니다(waconector 경유) — 제공업체를 선택하고 연결 세부 정보를 입력하세요. 자체 호스팅 제공업체는 별도로 실행되는 자체 서버/컨테이너가 필요합니다. 이것은 단지 거기에 연결할 뿐입니다.", + "settings.agentui.field.whatsapp.webhookUrl": "웹훅 URL — 제공업체의 대시보드에 붙여넣으세요", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "제공업체 측에서 설정할 웹훅 URL은 저장 후 여기에 표시됩니다.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/lo.ts b/packages/app/src/i18n/lo.ts index 18f1210f4865..41d9f141714e 100644 --- a/packages/app/src/i18n/lo.ts +++ b/packages/app/src/i18n/lo.ts @@ -827,6 +827,7 @@ export const dict = { "common.dismiss": "ປິດ", "common.moreCountSuffix": "(+{{count}} ເພີ່ມເຕີມ)", "common.requestFailed": "ການຮ້ອງຂໍລົ້ມເຫລວ", + "common.optional": "ທາງເລືອກ", "common.moreOptions": "ທາງເລືອກເພີ່ມເຕີມ", "common.learnMore": "ສຶກສາເພີ່ມເຕີມ", "common.rename": "ປ່ຽນຊື່", @@ -1436,6 +1437,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "ເປີດໜ້ານີ້ຈາກໂຄງການທີ່ເຊື່ອມຕໍ່ເພື່ອໃຫ້ຕົວແທນນີ້ມີບອດ Telegram ຂອງຕົນເອງ.", + "settings.agentui.error.whatsappIncomplete": "ເປີດໜ້ານີ້ຈາກໂຄງການທີ່ເຊື່ອມຕໍ່ ແລະ ຕື່ມຂໍ້ມູນທຸກຊ່ອງທີ່ຕ້ອງການສຳລັບຜູ້ໃຫ້ບໍລິການ WhatsApp ທີ່ເລືອກ.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1445,12 +1447,53 @@ export const dict = { "settings.agentui.ai.generate": "ສ້າງ", "settings.agentui.ai.generating": "ກຳລັງສ້າງ…", "settings.agentui.ai.toast.generated": "ຮ່າງຖືກສ້າງແລ້ວ — ກວດສອບກ່ອນບັນທຶກ", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "ໂທເຄັນບອດ (ທາງເລືອກ — ປະໄວ້ຫວ່າງເພື່ອແບ່ງປັນບອດທົ່ວໂລກ)", "settings.agentui.field.telegramToken.hint": "ວາງໂທເຄັນຈາກ @BotFather ເພື່ອໃຫ້ຕົວແທນນີ້ມີບອດ Telegram ສະເພາະຂອງຕົນເອງ. ປະໄວ້ຫວ່າງເພື່ອເຂົ້າເຖິງຜ່ານບອດທີ່ໃຊ້ຮ່ວມກັນໃນການຕັ້ງຄ່າ → ການເຊື່ອມໂຍງ, ໂດຍໃຊ້ຄຳນຳໜ້າຄຳສັ່ງຂອງມັນ.", + "settings.agentui.field.whatsapp": "ຕອບໃນ WhatsApp", + "settings.agentui.field.whatsapp.hint": "ໃຊ້ WhatsApp API ທີ່ບໍ່ເປັນທາງການ (ຜ່ານ waconector) — ເລືອກຜູ້ໃຫ້ບໍລິການ ແລະ ຕື່ມລາຍລະອຽດການເຊື່ອມຕໍ່. ຜູ້ໃຫ້ບໍລິການແບບ self-hosted ຕ້ອງການເຊີບເວີ/container ຂອງຕົນເອງແຍກຕ່າງຫາກ.", + "settings.agentui.field.whatsapp.webhookUrl": "URL Webhook — ວາງມັນໃນແດັຊບອດຂອງຜູ້ໃຫ້ບໍລິການ", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL Webhook ທີ່ຕ້ອງຕັ້ງຄ່າຢູ່ຝັ່ງຜູ້ໃຫ້ບໍລິການຈະປາກົດຢູ່ບ່ອນນີ້ຫຼັງຈາກທ່ານບັນທຶກ.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/lt.ts b/packages/app/src/i18n/lt.ts index e56e08ead217..15b996bc9c06 100644 --- a/packages/app/src/i18n/lt.ts +++ b/packages/app/src/i18n/lt.ts @@ -845,6 +845,7 @@ export const dict = { "common.dismiss": "Atsisakyti", "common.moreCountSuffix": "(+{{count}} daugiau)", "common.requestFailed": "Užklausa nepavyko", + "common.optional": "neprivaloma", "common.moreOptions": "Daugiau parinkčių", "common.learnMore": "Sužinokite daugiau", "common.rename": "Pervardyti", @@ -1461,6 +1462,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Atidarykite šį puslapį iš prijungto projekto, kad suteiktumėte šiam agentui savo Telegram botą.", + "settings.agentui.error.whatsappIncomplete": "Atidarykite šį puslapį iš prijungto projekto ir užpildykite visus privalomus pasirinkto WhatsApp teikėjo laukus.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1470,12 +1472,53 @@ export const dict = { "settings.agentui.ai.generate": "Generuoti", "settings.agentui.ai.generating": "Generuojama…", "settings.agentui.ai.toast.generated": "Juodraštis sukurtas — peržiūrėkite prieš išsaugant", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Boto žetonas (neprivaloma — palikite tuščią, kad bendrintumėte globalų botą)", "settings.agentui.field.telegramToken.hint": "Įklijuokite žetoną iš @BotFather, kad suteiktumėte šiam agentui savo skirtąjį Telegram botą. Palikite tuščią, kad pasiektumėte per bendrą botą skiltyje Nustatymai → Integracijos, naudojant jo komandos priešdėlį.", + "settings.agentui.field.whatsapp": "Atsakyti WhatsApp", + "settings.agentui.field.whatsapp.hint": "Naudoja neoficialų WhatsApp API (per waconector) — pasirinkite teikėją ir užpildykite ryšio duomenis. Savarankiškai talpinamiems teikėjams reikia atskirai veikiančio savo serverio/konteinerio.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — įklijuokite jį teikėjo skydelyje", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Webhook URL, kurį reikia sukonfigūruoti pas teikėją, pasirodo čia išsaugojus.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/lv.ts b/packages/app/src/i18n/lv.ts index fb9588b46366..d8fda3aec676 100644 --- a/packages/app/src/i18n/lv.ts +++ b/packages/app/src/i18n/lv.ts @@ -837,6 +837,7 @@ export const dict = { "common.dismiss": "Aizvērt", "common.moreCountSuffix": " (+{{count}} vēl)", "common.requestFailed": "Pieprasījums neizdevās", + "common.optional": "neobligāti", "common.moreOptions": "Vairāk opciju", "common.learnMore": "Uzzināt vairāk", "common.rename": "Pārdēvēt", @@ -1450,6 +1451,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Atveriet šo lapu no savienota projekta, lai piešķirtu šim aģentam savu Telegram botu.", + "settings.agentui.error.whatsappIncomplete": "Atveriet šo lapu no savienota projekta un aizpildiet visus obligātos laukus izvēlētajam WhatsApp nodrošinātājam.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1459,12 +1461,53 @@ export const dict = { "settings.agentui.ai.generate": "Ģenerēt", "settings.agentui.ai.generating": "Ģenerē…", "settings.agentui.ai.toast.generated": "Melnraksts izveidots — pārskatiet pirms saglabāšanas", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bota pilnvara (neobligāti — atstājiet tukšu, lai koplietotu globālo botu)", "settings.agentui.field.telegramToken.hint": "Ielīmējiet pilnvaru no @BotFather, lai piešķirtu šim aģentam savu īpašo Telegram botu. Atstājiet tukšu, lai piekļūtu, izmantojot kopīgo botu sadaļā Iestatījumi → Integrācijas, ar tā komandas prefiksu.", + "settings.agentui.field.whatsapp": "Atbildēt WhatsApp", + "settings.agentui.field.whatsapp.hint": "Izmanto neoficiālu WhatsApp API (izmantojot waconector) — izvēlieties nodrošinātāju un aizpildiet savienojuma datus. Pašmitinātiem nodrošinātājiem nepieciešams savs, atsevišķi darbojošs serveris/konteiners.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — ielīmējiet to nodrošinātāja panelī", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Webhook URL, kas jākonfigurē pie nodrošinātāja, parādās šeit pēc saglabāšanas.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/mk.ts b/packages/app/src/i18n/mk.ts index 26aa801c8125..dccef14d9af5 100644 --- a/packages/app/src/i18n/mk.ts +++ b/packages/app/src/i18n/mk.ts @@ -836,6 +836,7 @@ export const dict = { "common.dismiss": "Отфрли", "common.moreCountSuffix": "(+{{count}} повеќе)", "common.requestFailed": "Барањето не успеа", + "common.optional": "опционално", "common.moreOptions": "Повеќе опции", "common.learnMore": "Дознајте повеќе", "common.rename": "Преименувај", @@ -1454,6 +1455,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Отворете ја оваа страница од поврзан проект за да му дадете на овој агент сопствен Telegram бот.", + "settings.agentui.error.whatsappIncomplete": "Отворете ја оваа страница од поврзан проект и пополнете ги сите задолжителни полиња за избраниот WhatsApp давател.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1463,12 +1465,53 @@ export const dict = { "settings.agentui.ai.generate": "Генерирај", "settings.agentui.ai.generating": "Генерирање…", "settings.agentui.ai.toast.generated": "Нацрт е генериран — прегледајте пред да зачувате", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Токен на ботот (опционално — оставете празно за да го споделите глобалниот бот)", "settings.agentui.field.telegramToken.hint": "Залепете токен од @BotFather за да му дадете на овој агент сопствен наменски Telegram бот. Оставете празно за пристап преку споделениот бот во Поставки → Интеграции, користејќи го неговиот префикс за команда.", + "settings.agentui.field.whatsapp": "Одговори на WhatsApp", + "settings.agentui.field.whatsapp.hint": "Користи неофицијален WhatsApp API (преку waconector) — изберете давател и пополнете ги деталите за врска. Самостојно хостираните даватели бараат сопствен сервер/контејнер кој работи одделно.", + "settings.agentui.field.whatsapp.webhookUrl": "URL на webhook — залепете го во таблата на давателот", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL-от на webhook за конфигурирање кај давателот се појавува тука по зачувувањето.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/mn.ts b/packages/app/src/i18n/mn.ts index 14f66f7c50b8..4105ec8dfabb 100644 --- a/packages/app/src/i18n/mn.ts +++ b/packages/app/src/i18n/mn.ts @@ -839,6 +839,7 @@ export const dict = { "common.dismiss": "Хаах", "common.moreCountSuffix": "(+{{count}} илүү)", "common.requestFailed": "Хүсэлт амжилтгүй боллоо", + "common.optional": "заавал биш", "common.moreOptions": "Илүү олон сонголт", "common.learnMore": "Илүү ихийг мэдэж аваарай", "common.rename": "Нэрээ өөрчлөх", @@ -1456,6 +1457,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Энэ агентад өөрийн Telegram бот өгөхийн тулд холбогдсон төслөөс энэ хуудсыг нээнэ үү.", + "settings.agentui.error.whatsappIncomplete": "Энэ хуудсыг холбогдсон төслөөс нээж, сонгосон WhatsApp үйлчилгээ үзүүлэгчийн бүх шаардлагатай талбарыг бөглөнө үү.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1465,12 +1467,53 @@ export const dict = { "settings.agentui.ai.generate": "Үүсгэх", "settings.agentui.ai.generating": "Үүсгэж байна…", "settings.agentui.ai.toast.generated": "Ноорог үүсгэгдлээ — хадгалахын өмнө хянана уу", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Ботын токен (сонголттой — глобал ботыг хуваалцахын тулд хоосон орхино уу)", "settings.agentui.field.telegramToken.hint": "Энэ агентад өөрийн зориулалтын Telegram бот өгөхийн тулд @BotFather-ээс токеныг буулгана уу. Тохиргоо → Интеграциуд дахь хуваалцсан ботоор дамжуулан, түүний тушаалын угтвар ашиглан хандахын тулд хоосон орхино уу.", + "settings.agentui.field.whatsapp": "WhatsApp дээр хариулах", + "settings.agentui.field.whatsapp.hint": "Албан бус WhatsApp API ашигладаг (waconector-оор дамжуулан) — үйлчилгээ үзүүлэгчийг сонгож, холболтын мэдээллийг бөглөнө үү. Өөрөө байршуулсан үйлчилгээ үзүүлэгчид тусад нь ажиллаж буй өөрийн серверийг шаарддаг.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — үйлчилгээ үзүүлэгчийн хяналтын самбарт буулгана уу", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Үйлчилгээ үзүүлэгч дээр тохируулах Webhook URL хадгалсны дараа энд харагдана.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/ms.ts b/packages/app/src/i18n/ms.ts index 082f1268a676..29113777f3d7 100644 --- a/packages/app/src/i18n/ms.ts +++ b/packages/app/src/i18n/ms.ts @@ -831,6 +831,7 @@ export const dict = { "common.dismiss": "Abaikan", "common.moreCountSuffix": " (+{{count}} lagi)", "common.requestFailed": "Permintaan gagal", + "common.optional": "pilihan", "common.moreOptions": "Pilihan lanjut", "common.learnMore": "Ketahui lebih lanjut", "common.rename": "Tukar nama", @@ -1445,6 +1446,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Buka halaman ini daripada projek yang disambungkan untuk memberikan ejen ini bot Telegram tersendiri.", + "settings.agentui.error.whatsappIncomplete": "Buka halaman ini daripada projek yang disambungkan dan isikan semua medan wajib untuk pembekal WhatsApp yang dipilih.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1454,12 +1456,53 @@ export const dict = { "settings.agentui.ai.generate": "Jana", "settings.agentui.ai.generating": "Menjana…", "settings.agentui.ai.toast.generated": "Draf dijana — semak sebelum menyimpan", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token bot (pilihan — biarkan kosong untuk berkongsi bot global)", "settings.agentui.field.telegramToken.hint": "Tampal token daripada @BotFather untuk memberikan ejen ini bot Telegram khusus miliknya sendiri. Biarkan kosong untuk mengaksesnya melalui bot yang dikongsi dalam Tetapan → Integrasi, menggunakan awalan arahannya.", + "settings.agentui.field.whatsapp": "Balas di WhatsApp", + "settings.agentui.field.whatsapp.hint": "Menggunakan API WhatsApp tidak rasmi (melalui waconector) — pilih pembekal dan isikan butiran sambungan. Pembekal self-hosted memerlukan pelayan/bekas sendiri yang berjalan berasingan.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhook — tampalkan ke papan pemuka pembekal", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL webhook yang perlu dikonfigurasikan di pihak pembekal muncul di sini selepas anda menyimpan.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/my.ts b/packages/app/src/i18n/my.ts index 9eda89d52c09..5cd2c2d05f84 100644 --- a/packages/app/src/i18n/my.ts +++ b/packages/app/src/i18n/my.ts @@ -841,6 +841,7 @@ export const dict = { "common.dismiss": "ပယ်ရန်", "common.moreCountSuffix": "(+{{count}} နောက်ထပ်)", "common.requestFailed": "တောင်းဆိုမှု မအောင်မြင်ပါ။", + "common.optional": "ရွေးချယ်နိုင်သော", "common.moreOptions": "နောက်ထပ် ရွေးချယ်စရာများ", "common.learnMore": "ပိုမိုလေ့လာရန်", "common.rename": "အမည်ပြောင်း", @@ -1464,6 +1465,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "ဤအေးဂျင့်ကို ၎င်း၏ကိုယ်ပိုင် Telegram ဘော့ပေးရန် ချိတ်ဆက်ထားသော ပရောဂျက်မှ ဤစာမျက်နှာကို ဖွင့်ပါ။", + "settings.agentui.error.whatsappIncomplete": "ချိတ်ဆက်ထားသော ပရောဂျက်မှ ဤစာမျက်နှာကို ဖွင့်ပြီး ရွေးချယ်ထားသော WhatsApp ဝန်ဆောင်မှုပေးသူအတွက် လိုအပ်သော ကွက်လပ်များအားလုံးကို ဖြည့်ပါ။", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1473,12 +1475,53 @@ export const dict = { "settings.agentui.ai.generate": "ဖန်တီးမည်", "settings.agentui.ai.generating": "ဖန်တီးနေသည်…", "settings.agentui.ai.toast.generated": "မူကြမ်း ဖန်တီးပြီးပါပြီ — သိမ်းဆည်းမီ စစ်ဆေးပါ", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "ဘော့တိုကင် (ရွေးချယ်နိုင် — ကမ္ဘာလုံးဆိုင်ရာဘော့ကို မျှဝေရန် ဗလာထားပါ)", "settings.agentui.field.telegramToken.hint": "ဤအေးဂျင့်ကို ၎င်း၏ကိုယ်ပိုင် Telegram ဘော့ပေးရန် @BotFather မှ တိုကင်ကို ကူးထည့်ပါ။ ဆက်တင်များ → ပေါင်းစည်းမှုများရှိ မျှဝေထားသောဘော့မှတစ်ဆင့် ၎င်း၏ command prefix ကိုအသုံးပြု၍ ချိတ်ဆက်ရန် ဗလာထားပါ။", + "settings.agentui.field.whatsapp": "WhatsApp တွင် ပြန်ကြားမည်", + "settings.agentui.field.whatsapp.hint": "တရားမဝင် WhatsApp API ကို အသုံးပြုသည် (waconector မှတဆင့်) — ဝန်ဆောင်မှုပေးသူတစ်ခုကို ရွေးပြီး ချိတ်ဆက်မှုအသေးစိတ်ကို ဖြည့်ပါ။", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — ဝန်ဆောင်မှုပေးသူ၏ dashboard တွင် ကူးထည့်ပါ", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "ဝန်ဆောင်မှုပေးသူဘက်တွင် စီစဉ်ရမည့် Webhook URL သည် သိမ်းဆည်းပြီးနောက် ဤနေရာတွင် ပေါ်လာမည်။", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/ne.ts b/packages/app/src/i18n/ne.ts index 2f50a21b4961..2fd38a9c0874 100644 --- a/packages/app/src/i18n/ne.ts +++ b/packages/app/src/i18n/ne.ts @@ -833,6 +833,7 @@ export const dict: Record = { "common.dismiss": "खारेज गर्नुहोस्", "common.moreCountSuffix": "(+{{count}} थप)", "common.requestFailed": "अनुरोध असफल भयो", + "common.optional": "वैकल्पिक", "common.moreOptions": "थप विकल्पहरू", "common.learnMore": "थप जान्नुहोस्", "common.rename": "पुन: नामाकरण गर्नुहोस्", @@ -1445,6 +1446,7 @@ export const dict: Record = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "यस एजेन्टलाई आफ्नै टेलिग्राम बोट दिन जडित प्रोजेक्टबाट यो पृष्ठ खोल्नुहोस्।", + "settings.agentui.error.whatsappIncomplete": "जडित प्रोजेक्टबाट यो पृष्ठ खोल्नुहोस् र चयनित WhatsApp प्रदायकका सबै आवश्यक फिल्डहरू भर्नुहोस्।", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1454,12 +1456,53 @@ export const dict: Record = { "settings.agentui.ai.generate": "उत्पन्न गर्नुहोस्", "settings.agentui.ai.generating": "उत्पन्न गर्दै…", "settings.agentui.ai.toast.generated": "मस्यौदा उत्पन्न भयो — सुरक्षित गर्नु अघि समीक्षा गर्नुहोस्", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "बोट टोकन (वैकल्पिक — ग्लोबल बोट साझा गर्न खाली छोड्नुहोस्)", "settings.agentui.field.telegramToken.hint": "यस एजेन्टलाई आफ्नै समर्पित टेलिग्राम बोट दिन @BotFather बाट टोकन टाँस्नुहोस्। सेटिङ्स → इन्टिग्रेसनहरूमा साझा बोट मार्फत, यसको कमान्ड ट्रिगर प्रयोग गरेर पहुँच गर्न खाली छोड्नुहोस्।", + "settings.agentui.field.whatsapp": "WhatsApp मा जवाफ दिनुहोस्", + "settings.agentui.field.whatsapp.hint": "एक गैर-आधिकारिक WhatsApp API प्रयोग गर्दछ (waconector मार्फत) — प्रदायक छान्नुहोस् र जडान विवरण भर्नुहोस्। स्व-होस्ट गरिएका प्रदायकहरूलाई छुट्टै चलिरहेको आफ्नै सर्भर/कन्टेनर चाहिन्छ।", + "settings.agentui.field.whatsapp.webhookUrl": "वेबहुक URL — प्रदायकको ड्यासबोर्डमा टाँस्नुहोस्", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "प्रदायकतर्फ कन्फिगर गर्नुपर्ने वेबहुक URL सुरक्षित गरेपछि यहाँ देखिन्छ।", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/nl.ts b/packages/app/src/i18n/nl.ts index 0aa5a1aaa846..36b8f8055b2b 100644 --- a/packages/app/src/i18n/nl.ts +++ b/packages/app/src/i18n/nl.ts @@ -841,6 +841,7 @@ export const dict = { "common.dismiss": "Negeren", "common.moreCountSuffix": " (+{{count}} meer)", "common.requestFailed": "Verzoek mislukt", + "common.optional": "optioneel", "common.moreOptions": "Meer opties", "common.learnMore": "Meer informatie", "common.rename": "Hernoemen", @@ -1459,6 +1460,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Open deze pagina vanuit een verbonden project om deze agent zijn eigen Telegram-bot te geven.", + "settings.agentui.error.whatsappIncomplete": "Open deze pagina vanuit een verbonden project en vul alle verplichte velden in voor de geselecteerde WhatsApp-provider.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1468,12 +1470,53 @@ export const dict = { "settings.agentui.ai.generate": "Genereren", "settings.agentui.ai.generating": "Genereren…", "settings.agentui.ai.toast.generated": "Concept gegenereerd — controleer voordat je opslaat", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot-token (optioneel — laat leeg om de globale bot te delen)", "settings.agentui.field.telegramToken.hint": "Plak een token van @BotFather om deze agent zijn eigen toegewijde Telegram-bot te geven. Laat leeg om hem te bereiken via de gedeelde bot in Instellingen → Integraties, met zijn opdrachtprefix.", + "settings.agentui.field.whatsapp": "Reageren op WhatsApp", + "settings.agentui.field.whatsapp.hint": "Gebruikt een niet-officiële WhatsApp-API (via waconector) — kies een provider en vul de verbindingsgegevens in. Self-hosted providers hebben hun eigen, apart draaiende server/container nodig; dit maakt er alleen verbinding mee.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook-URL — plak deze in het dashboard van de provider", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "De bij de provider te configureren webhook-URL verschijnt hier na het opslaan.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/no.ts b/packages/app/src/i18n/no.ts index 3b0ad3a2b976..ede2cca5559d 100644 --- a/packages/app/src/i18n/no.ts +++ b/packages/app/src/i18n/no.ts @@ -730,6 +730,7 @@ export const dict = { "common.closeTab": "Lukk fane", "common.dismiss": "Avvis", "common.requestFailed": "Forespørsel mislyktes", + "common.optional": "valgfritt", "common.moreOptions": "Flere alternativer", "common.learnMore": "Lær mer", "common.rename": "Gi nytt navn", @@ -1555,6 +1556,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Åpne denne siden fra et tilkoblet prosjekt for å gi denne agenten sin egen Telegram-bot.", + "settings.agentui.error.whatsappIncomplete": "Åpne denne siden fra et tilkoblet prosjekt og fyll ut alle påkrevde felt for den valgte WhatsApp-leverandøren.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1564,12 +1566,53 @@ export const dict = { "settings.agentui.ai.generate": "Generer", "settings.agentui.ai.generating": "Genererer…", "settings.agentui.ai.toast.generated": "Utkast generert — se gjennom før du lagrer", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot-token (valgfritt — la stå tomt for å dele den globale boten)", "settings.agentui.field.telegramToken.hint": "Lim inn et token fra @BotFather for å gi denne agenten sin egen dedikerte Telegram-bot. La stå tomt for å nå den via den delte boten i Innstillinger → Integrasjoner, med kommandoprefikset.", + "settings.agentui.field.whatsapp": "Svar på WhatsApp", + "settings.agentui.field.whatsapp.hint": "Bruker en uoffisiell WhatsApp-API (via waconector) — velg en leverandør og fyll ut tilkoblingsdetaljene. Selvhostede leverandører krever sin egen server/beholder som kjører separat.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook-URL — lim den inn i leverandørens dashbord", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Webhook-URL-en som skal konfigureres hos leverandøren, vises her etter at du har lagret.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/pa.ts b/packages/app/src/i18n/pa.ts index d785d43af3ec..f6917769be3d 100644 --- a/packages/app/src/i18n/pa.ts +++ b/packages/app/src/i18n/pa.ts @@ -840,6 +840,7 @@ export const dict = { "common.dismiss": "برخاست کرو", "common.moreCountSuffix": " (+{{count}} ہور)", "common.requestFailed": "درخواست ناکام ہو گئی", + "common.optional": "ਵਿਕਲਪਿਕ", "common.moreOptions": "ہور اختیارات", "common.learnMore": "ہور جانو", "common.rename": "ناں بدلو", @@ -1449,6 +1450,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "ਇਸ ਏਜੰਟ ਨੂੰ ਆਪਣਾ ਖੁਦ ਦਾ ਟੈਲੀਗ੍ਰਾਮ ਬੋਟ ਦੇਣ ਲਈ ਇੱਕ ਕਨੈਕਟ ਕੀਤੇ ਪ੍ਰੋਜੈਕਟ ਤੋਂ ਇਹ ਪੰਨਾ ਖੋਲ੍ਹੋ।", + "settings.agentui.error.whatsappIncomplete": "ਇੱਕ ਕਨੈਕਟ ਕੀਤੇ ਪ੍ਰੋਜੈਕਟ ਤੋਂ ਇਹ ਪੰਨਾ ਖੋਲ੍ਹੋ ਅਤੇ ਚੁਣੇ ਗਏ WhatsApp ਪ੍ਰਦਾਤਾ ਲਈ ਸਾਰੇ ਲੋੜੀਂਦੇ ਖੇਤਰ ਭਰੋ।", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1458,12 +1460,53 @@ export const dict = { "settings.agentui.ai.generate": "ਬਣਾਓ", "settings.agentui.ai.generating": "ਬਣਾਇਆ ਜਾ ਰਿਹਾ ਹੈ…", "settings.agentui.ai.toast.generated": "ਡਰਾਫਟ ਬਣਾਇਆ ਗਿਆ — ਸੰਭਾਲਣ ਤੋਂ ਪਹਿਲਾਂ ਸਮੀਖਿਆ ਕਰੋ", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "ਬੋਟ ਟੋਕਨ (ਵਿਕਲਪਿਕ — ਗਲੋਬਲ ਬੋਟ ਸਾਂਝਾ ਕਰਨ ਲਈ ਖਾਲੀ ਛੱਡੋ)", "settings.agentui.field.telegramToken.hint": "ਇਸ ਏਜੰਟ ਨੂੰ ਆਪਣਾ ਸਮਰਪਿਤ ਟੈਲੀਗ੍ਰਾਮ ਬੋਟ ਦੇਣ ਲਈ @BotFather ਤੋਂ ਟੋਕਨ ਪੇਸਟ ਕਰੋ। ਸੈਟਿੰਗਾਂ → ਏਕੀਕਰਨ ਵਿੱਚ ਸਾਂਝੇ ਬੋਟ ਰਾਹੀਂ, ਇਸਦੇ ਕਮਾਂਡ ਟਰਿੱਗਰ ਦੀ ਵਰਤੋਂ ਕਰਕੇ ਪਹੁੰਚਣ ਲਈ ਖਾਲੀ ਛੱਡੋ।", + "settings.agentui.field.whatsapp": "WhatsApp 'ਤੇ ਜਵਾਬ ਦਿਓ", + "settings.agentui.field.whatsapp.hint": "ਇੱਕ ਗੈਰ-ਅਧਿਕਾਰਤ WhatsApp API ਵਰਤਦਾ ਹੈ (waconector ਰਾਹੀਂ) — ਇੱਕ ਪ੍ਰਦਾਤਾ ਚੁਣੋ ਅਤੇ ਕਨੈਕਸ਼ਨ ਵੇਰਵੇ ਭਰੋ। ਸਵੈ-ਹੋਸਟ ਕੀਤੇ ਪ੍ਰਦਾਤਾਵਾਂ ਨੂੰ ਆਪਣਾ ਵੱਖਰੇ ਤੌਰ 'ਤੇ ਚੱਲ ਰਿਹਾ ਸਰਵਰ/ਕੰਟੇਨਰ ਚਾਹੀਦਾ ਹੈ।", + "settings.agentui.field.whatsapp.webhookUrl": "ਵੈਬਹੁੱਕ URL — ਇਸਨੂੰ ਪ੍ਰਦਾਤਾ ਦੇ ਡੈਸ਼ਬੋਰਡ ਵਿੱਚ ਪੇਸਟ ਕਰੋ", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "ਪ੍ਰਦਾਤਾ ਵੱਲੋਂ ਕੌਂਫਿਗਰ ਕਰਨ ਲਈ ਵੈਬਹੁੱਕ URL ਸੰਭਾਲਣ ਤੋਂ ਬਾਅਦ ਇੱਥੇ ਦਿਖਾਈ ਦਿੰਦਾ ਹੈ।", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/parity.test.ts b/packages/app/src/i18n/parity.test.ts index d2f1ed35d140..d758201fa49c 100644 --- a/packages/app/src/i18n/parity.test.ts +++ b/packages/app/src/i18n/parity.test.ts @@ -74,6 +74,13 @@ const pluralCategories = new Map( ] as const, ), ) +// "dv" (Divehi): Intl.PluralRules' resolved categories for this locale +// disagree across ICU builds (seen: Windows resolves ["one","many","other"], +// Linux CI resolves ["one","other"] — see issue #197). Every dv.ts already +// only carries .one/.other (no .many/.few/.two/.zero content), so pin an +// empty extra-category list here instead of letting the platform decide — +// makes this test deterministic across OSes without touching translations. +pluralCategories.set("dv", []) const domains = [ { diff --git a/packages/app/src/i18n/pl.ts b/packages/app/src/i18n/pl.ts index 793b2b22a94b..62f1092f51e4 100644 --- a/packages/app/src/i18n/pl.ts +++ b/packages/app/src/i18n/pl.ts @@ -806,6 +806,7 @@ export const dict = { "common.closeTab": "Zamknij kartę", "common.dismiss": "Odrzuć", "common.requestFailed": "Żądanie nie powiodło się", + "common.optional": "opcjonalnie", "common.moreOptions": "Więcej opcji", "common.learnMore": "Dowiedz się więcej", "common.rename": "Zmień nazwę", @@ -1472,6 +1473,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Otwórz tę stronę z połączonego projektu, aby nadać temu agentowi własnego bota Telegram.", + "settings.agentui.error.whatsappIncomplete": "Otwórz tę stronę z połączonego projektu i wypełnij wszystkie wymagane pola dla wybranego dostawcy WhatsApp.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1481,12 +1483,53 @@ export const dict = { "settings.agentui.ai.generate": "Generuj", "settings.agentui.ai.generating": "Generowanie…", "settings.agentui.ai.toast.generated": "Szkic wygenerowany — sprawdź przed zapisaniem", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token bota (opcjonalnie — zostaw puste, aby współdzielić globalnego bota)", "settings.agentui.field.telegramToken.hint": "Wklej token od @BotFather, aby nadać temu agentowi własnego dedykowanego bota Telegram. Zostaw puste, aby uzyskać dostęp przez współdzielonego bota w Ustawienia → Integracje, używając jego prefiksu komendy.", + "settings.agentui.field.whatsapp": "Odpowiadaj na WhatsApp", + "settings.agentui.field.whatsapp.hint": "Używa nieoficjalnego API WhatsApp (przez waconector) — wybierz dostawcę i wypełnij dane połączenia. Dostawcy self-hosted wymagają własnego, osobno działającego serwera/kontenera; to tylko się z nim łączy.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhooka — wklej go w panelu dostawcy", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL webhooka do skonfigurowania u dostawcy pojawia się tutaj po zapisaniu.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/ro.ts b/packages/app/src/i18n/ro.ts index da0df020bca2..a6b0082859b7 100644 --- a/packages/app/src/i18n/ro.ts +++ b/packages/app/src/i18n/ro.ts @@ -837,6 +837,7 @@ export const dict = { "common.dismiss": "Închide", "common.moreCountSuffix": " (+{{count}} în plus)", "common.requestFailed": "Solicitarea a eșuat", + "common.optional": "opțional", "common.moreOptions": "Mai multe opțiuni", "common.learnMore": "Află mai mult", "common.rename": "Redenumește", @@ -1450,6 +1451,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Deschide această pagină dintr-un proiect conectat pentru a oferi acestui agent propriul bot Telegram.", + "settings.agentui.error.whatsappIncomplete": "Deschide această pagină dintr-un proiect conectat și completează toate câmpurile obligatorii pentru furnizorul WhatsApp selectat.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1459,12 +1461,53 @@ export const dict = { "settings.agentui.ai.generate": "Generează", "settings.agentui.ai.generating": "Se generează…", "settings.agentui.ai.toast.generated": "Ciornă generată — revizuiește înainte de a salva", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token bot (opțional — lasă gol pentru a partaja botul global)", "settings.agentui.field.telegramToken.hint": "Lipește un token de la @BotFather pentru a oferi acestui agent propriul bot Telegram dedicat. Lasă gol pentru a-l accesa prin botul partajat din Setări → Integrări, folosind prefixul său de comandă.", + "settings.agentui.field.whatsapp": "Răspunde pe WhatsApp", + "settings.agentui.field.whatsapp.hint": "Folosește un API WhatsApp neoficial (prin waconector) — alege un furnizor și completează detaliile de conexiune. Furnizorii auto-găzduiți necesită propriul server/container care rulează separat.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhook — lipește-l în panoul furnizorului", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL-ul webhook de configurat la furnizor apare aici după salvare.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/ru.ts b/packages/app/src/i18n/ru.ts index 3be062aa6a8c..e237e0471db8 100644 --- a/packages/app/src/i18n/ru.ts +++ b/packages/app/src/i18n/ru.ts @@ -867,6 +867,7 @@ export const dict = { "common.closeTab": "Закрыть вкладку", "common.dismiss": "Закрыть", "common.requestFailed": "Запрос не выполнен", + "common.optional": "необязательно", "common.moreOptions": "Дополнительные опции", "common.learnMore": "Подробнее", "common.rename": "Переименовать", @@ -1550,6 +1551,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Откройте эту страницу из подключённого проекта, чтобы дать этому агенту собственного Telegram-бота.", + "settings.agentui.error.whatsappIncomplete": "Откройте эту страницу из подключённого проекта и заполните все обязательные поля для выбранного провайдера WhatsApp.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1559,12 +1561,53 @@ export const dict = { "settings.agentui.ai.generate": "Сгенерировать", "settings.agentui.ai.generating": "Генерация…", "settings.agentui.ai.toast.generated": "Черновик создан — проверьте перед сохранением", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Токен бота (необязательно — оставьте пустым, чтобы использовать общий бот)", "settings.agentui.field.telegramToken.hint": "Вставьте токен от @BotFather, чтобы дать этому агенту собственного выделенного Telegram-бота. Оставьте пустым, чтобы обращаться к нему через общий бот в Настройки → Интеграции, используя его командный префикс.", + "settings.agentui.field.whatsapp": "Отвечать в WhatsApp", + "settings.agentui.field.whatsapp.hint": "Использует неофициальный WhatsApp API (через waconector) — выберите провайдера и заполните данные подключения. Провайдерам с самостоятельным хостингом нужен собственный, отдельно работающий сервер/контейнер; это лишь подключается к нему.", + "settings.agentui.field.whatsapp.webhookUrl": "URL вебхука — вставьте его в панель провайдера", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL вебхука, который нужно настроить у провайдера, появится здесь после сохранения.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/si.ts b/packages/app/src/i18n/si.ts index cc0a8c8ebce7..6fb1d3cd6fdd 100644 --- a/packages/app/src/i18n/si.ts +++ b/packages/app/src/i18n/si.ts @@ -829,6 +829,7 @@ export const dict: Record = { "common.dismiss": "අස් කරන්න", "common.moreCountSuffix": "(+{{count}} තව)", "common.requestFailed": "ඉල්ලීම අසාර්ථක විය", + "common.optional": "විකල්ප", "common.moreOptions": "තවත් විකල්ප", "common.learnMore": "තවත් හදාරන්න", "common.rename": "නැවත නම් කරන්න", @@ -1441,6 +1442,7 @@ export const dict: Record = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "මෙම නියෝජිතයාට තමන්ගේම ටෙලිග්‍රාම් බොට් එකක් ලබා දීමට සම්බන්ධිත ව්‍යාපෘතියකින් මෙම පිටුව විවෘත කරන්න.", + "settings.agentui.error.whatsappIncomplete": "සම්බන්ධිත ව්‍යාපෘතියකින් මෙම පිටුව විවෘත කර තෝරාගත් WhatsApp සැපයුම්කරු සඳහා අවශ්‍ය සියලුම ක්ෂේත්‍ර පුරවන්න.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1450,12 +1452,53 @@ export const dict: Record = { "settings.agentui.ai.generate": "උත්පාදනය කරන්න", "settings.agentui.ai.generating": "උත්පාදනය කරමින්…", "settings.agentui.ai.toast.generated": "කෙටුම්පත සාදන ලදී — සුරැකීමට පෙර සමාලෝචනය කරන්න", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "බොට් ටෝකනය (විකල්ප — ගෝලීය බොට් බෙදාගැනීමට හිස්ව තබන්න)", "settings.agentui.field.telegramToken.hint": "මෙම නියෝජිතයාට තමන්ගේම කැපවූ ටෙලිග්‍රාම් බොට් එකක් ලබා දීමට @BotFather වෙතින් ටෝකනයක් අලවන්න. සැකසීම් → ඒකාබද්ධ කිරීම් හි ඇති බෙදාගත් බොට් හරහා, එහි විධාන උපසර්ගය භාවිතයෙන් ළඟා වීමට හිස්ව තබන්න.", + "settings.agentui.field.whatsapp": "WhatsApp හි පිළිතුරු දෙන්න", + "settings.agentui.field.whatsapp.hint": "නිල නොවන WhatsApp API එකක් භාවිතා කරයි (waconector හරහා) — සැපයුම්කරුවෙකු තෝරා සම්බන්ධතා විස්තර පුරවන්න. self-hosted සැපයුම්කරුවන්ට වෙනම ධාවනය වන තමන්ගේම සර්වර්/කන්ටේනරයක් අවශ්‍යයි.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — එය සැපයුම්කරුගේ dashboard එකට අලවන්න", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "සැපයුම්කරු පැත්තෙන් වින්‍යාස කළ යුතු Webhook URL එක සුරැකීමෙන් පසු මෙහි දිස්වේ.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/sk.ts b/packages/app/src/i18n/sk.ts index 0fcf8e5d494e..a68d4765ad92 100644 --- a/packages/app/src/i18n/sk.ts +++ b/packages/app/src/i18n/sk.ts @@ -835,6 +835,7 @@ export const dict = { "common.dismiss": "Zavrieť", "common.moreCountSuffix": " (+{{count}} ďalšie)", "common.requestFailed": "Požiadavka zlyhala", + "common.optional": "voliteľné", "common.moreOptions": "Viac možností", "common.learnMore": "Zistiť viac", "common.rename": "Premenovať", @@ -1447,6 +1448,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Otvorte túto stránku z pripojeného projektu, aby ste tomuto agentovi dali vlastného Telegram bota.", + "settings.agentui.error.whatsappIncomplete": "Otvorte túto stránku z pripojeného projektu a vyplňte všetky povinné polia pre vybraného poskytovateľa WhatsApp.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1456,12 +1458,53 @@ export const dict = { "settings.agentui.ai.generate": "Vygenerovať", "settings.agentui.ai.generating": "Generuje sa…", "settings.agentui.ai.toast.generated": "Návrh vygenerovaný — pred uložením skontrolujte", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token bota (voliteľné — nechajte prázdne pre zdieľanie globálneho bota)", "settings.agentui.field.telegramToken.hint": "Vložte token od @BotFather, aby ste tomuto agentovi dali vlastného vyhradeného Telegram bota. Nechajte prázdne pre prístup cez zdieľaného bota v Nastavenia → Integrácie, pomocou jeho príkazovej predpony.", + "settings.agentui.field.whatsapp": "Odpovedať na WhatsApp", + "settings.agentui.field.whatsapp.hint": "Používa neoficiálne WhatsApp API (cez waconector) — vyberte poskytovateľa a vyplňte údaje o pripojení. Self-hosted poskytovatelia potrebujú vlastný, samostatne bežiaci server/kontajner.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhooku — vložte ho do panela poskytovateľa", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL webhooku na konfiguráciu u poskytovateľa sa zobrazí tu po uložení.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/sl.ts b/packages/app/src/i18n/sl.ts index 85e28facdeca..754a085f1665 100644 --- a/packages/app/src/i18n/sl.ts +++ b/packages/app/src/i18n/sl.ts @@ -837,6 +837,7 @@ export const dict = { "common.dismiss": "Odpusti", "common.moreCountSuffix": " (+{{count}} več)", "common.requestFailed": "Zahteva ni uspela", + "common.optional": "neobvezno", "common.moreOptions": "Več možnosti", "common.learnMore": "Več o tem", "common.rename": "Preimenuj", @@ -1451,6 +1452,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Odprite to stran iz povezanega projekta, da temu agentu dodelite lastnega Telegram bota.", + "settings.agentui.error.whatsappIncomplete": "Odprite to stran iz povezanega projekta in izpolnite vsa obvezna polja za izbranega ponudnika WhatsApp.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1460,12 +1462,53 @@ export const dict = { "settings.agentui.ai.generate": "Ustvari", "settings.agentui.ai.generating": "Ustvarjanje…", "settings.agentui.ai.toast.generated": "Osnutek ustvarjen — preglejte pred shranjevanjem", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Žeton bota (neobvezno — pustite prazno za skupno rabo globalnega bota)", "settings.agentui.field.telegramToken.hint": "Prilepite žeton od @BotFather, da temu agentu dodelite lastnega namenskega Telegram bota. Pustite prazno za dostop prek skupnega bota v Nastavitve → Integracije, z uporabo njegove predpone ukaza.", + "settings.agentui.field.whatsapp": "Odgovori na WhatsAppu", + "settings.agentui.field.whatsapp.hint": "Uporablja neuradni WhatsApp API (prek waconector) — izberite ponudnika in izpolnite podatke o povezavi. Samostojno gostovani ponudniki potrebujejo svoj ločeno delujoč strežnik/vsebnik.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhooka — prilepite ga v nadzorno ploščo ponudnika", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL webhooka za konfiguracijo pri ponudniku se prikaže tukaj po shranjevanju.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/sq.ts b/packages/app/src/i18n/sq.ts index 7234cfd3552d..053c26fd6fb8 100644 --- a/packages/app/src/i18n/sq.ts +++ b/packages/app/src/i18n/sq.ts @@ -835,6 +835,7 @@ export const dict = { "common.dismiss": "Largoje", "common.moreCountSuffix": " (+{{count}} më shumë)", "common.requestFailed": "Kërkesa dështoi", + "common.optional": "opsionale", "common.moreOptions": "Më shumë opsione", "common.learnMore": "Mësoni më shumë", "common.rename": "Riemërto", @@ -1451,6 +1452,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Hapni këtë faqe nga një projekt i lidhur për t'i dhënë këtij agjenti botin e vet të Telegram.", + "settings.agentui.error.whatsappIncomplete": "Hapni këtë faqe nga një projekt i lidhur dhe plotësoni të gjitha fushat e detyrueshme për ofruesin e zgjedhur të WhatsApp.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1460,12 +1462,53 @@ export const dict = { "settings.agentui.ai.generate": "Gjenero", "settings.agentui.ai.generating": "Duke gjeneruar…", "settings.agentui.ai.toast.generated": "Skica u gjenerua — shqyrtojeni para se ta ruani", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token i botit (opsional — lëreni bosh për të ndarë botin global)", "settings.agentui.field.telegramToken.hint": "Ngjitni një token nga @BotFather për t'i dhënë këtij agjenti botin e tij të dedikuar të Telegram. Lëreni bosh për ta arritur përmes botit të përbashkët në Cilësimet → Integrimet, duke përdorur prefiksin e tij të komandës.", + "settings.agentui.field.whatsapp": "Përgjigju në WhatsApp", + "settings.agentui.field.whatsapp.hint": "Përdor një API jozyrtare WhatsApp (përmes waconector) — zgjidhni një ofrues dhe plotësoni detajet e lidhjes. Ofruesit e vetë-strehuar kërkojnë serverin/kontejnerin e tyre që funksionon veçmas.", + "settings.agentui.field.whatsapp.webhookUrl": "URL i webhook — ngjiteni në panelin e ofruesit", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL i webhook për t'u konfiguruar te ofruesi shfaqet këtu pas ruajtjes.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/sr.ts b/packages/app/src/i18n/sr.ts index 3ae80a1028f1..1e5fdb3064fb 100644 --- a/packages/app/src/i18n/sr.ts +++ b/packages/app/src/i18n/sr.ts @@ -835,6 +835,7 @@ export const dict = { "common.dismiss": "Одбаци", "common.moreCountSuffix": "(+{{count}} више)", "common.requestFailed": "Захтев није успео", + "common.optional": "опционо", "common.moreOptions": "Више опција", "common.learnMore": "Сазнајте више", "common.rename": "Преименуј", @@ -1449,6 +1450,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Отворите ову страницу из повезаног пројекта да бисте овом агенту дали сопственог Telegram бота.", + "settings.agentui.error.whatsappIncomplete": "Отворите ову страницу из повезаног пројекта и попуните сва обавезна поља за изабраног WhatsApp добављача.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1458,12 +1460,53 @@ export const dict = { "settings.agentui.ai.generate": "Генериши", "settings.agentui.ai.generating": "Генерисање…", "settings.agentui.ai.toast.generated": "Нацрт је генерисан — прегледајте пре чувања", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Токен бота (опционо — оставите празно да делите глобални бот)", "settings.agentui.field.telegramToken.hint": "Налепите токен са @BotFather да бисте овом агенту дали сопственог наменског Telegram бота. Оставите празно за приступ преко заједничког бота у Подешавања → Интеграције, користећи његов префикс команде.", + "settings.agentui.field.whatsapp": "Одговори на WhatsApp-у", + "settings.agentui.field.whatsapp.hint": "Користи незваничан WhatsApp API (преко waconector) — изаберите добављача и попуните податке о вези. Самостално хостовани добављачи захтевају сопствени сервер/контејнер који ради одвојено.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhook-а — налепите га у контролну таблу добављача", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL webhook-а за конфигурисање код добављача се приказује овде након чувања.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/sv.ts b/packages/app/src/i18n/sv.ts index 5168afcb4c7a..ea99392c0a69 100644 --- a/packages/app/src/i18n/sv.ts +++ b/packages/app/src/i18n/sv.ts @@ -837,6 +837,7 @@ export const dict = { "common.dismiss": "Avfärda", "common.moreCountSuffix": " (+{{count}} till)", "common.requestFailed": "Begäran misslyckades", + "common.optional": "valfritt", "common.moreOptions": "Fler alternativ", "common.learnMore": "Läs mer", "common.rename": "Byt namn", @@ -1448,6 +1449,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Öppna denna sida från ett anslutet projekt för att ge denna agent sin egen Telegram-bot.", + "settings.agentui.error.whatsappIncomplete": "Öppna denna sida från ett anslutet projekt och fyll i alla obligatoriska fält för den valda WhatsApp-leverantören.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1457,12 +1459,53 @@ export const dict = { "settings.agentui.ai.generate": "Generera", "settings.agentui.ai.generating": "Genererar…", "settings.agentui.ai.toast.generated": "Utkast genererat — granska innan du sparar", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot-token (valfritt — lämna tomt för att dela den globala boten)", "settings.agentui.field.telegramToken.hint": "Klistra in ett token från @BotFather för att ge denna agent sin egen dedikerade Telegram-bot. Lämna tomt för att nå den via den delade boten i Inställningar → Integrationer, med dess kommandoprefix.", + "settings.agentui.field.whatsapp": "Svara på WhatsApp", + "settings.agentui.field.whatsapp.hint": "Använder ett inofficiellt WhatsApp-API (via waconector) — välj en leverantör och fyll i anslutningsuppgifterna. Självhostade leverantörer kräver en egen, separat körande server/behållare.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook-URL — klistra in den i leverantörens dashboard", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Webhook-URL:en som ska konfigureras hos leverantören visas här efter att du sparat.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/tg.ts b/packages/app/src/i18n/tg.ts index 83d2489f4b31..3e09a2bbac74 100644 --- a/packages/app/src/i18n/tg.ts +++ b/packages/app/src/i18n/tg.ts @@ -835,6 +835,7 @@ export const dict = { "common.dismiss": "Рад кардан", "common.moreCountSuffix": "(+{{count}} бештар)", "common.requestFailed": "Дархост иҷро нашуд", + "common.optional": "ихтиёрӣ", "common.moreOptions": "Имконоти бештар", "common.learnMore": "Бисёр омӯхтан", "common.rename": "Номи дигар", @@ -1452,6 +1453,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Ин саҳифаро аз лоиҳаи пайвастшуда кушоед, то ба ин агент боти шахсии Telegram диҳед.", + "settings.agentui.error.whatsappIncomplete": "Ин саҳифаро аз лоиҳаи пайвастшуда кушоед ва ҳамаи майдонҳои ҳатмии провайдери WhatsApp интихобшударо пур кунед.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1461,12 +1463,53 @@ export const dict = { "settings.agentui.ai.generate": "Тавлид кардан", "settings.agentui.ai.generating": "Тавлид карда истодааст…", "settings.agentui.ai.toast.generated": "Лоиҳа тавлид шуд — пеш аз сабт дидан кунед", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Токени бот (ихтиёрӣ — барои мубодилаи боти глобалӣ холӣ гузоред)", "settings.agentui.field.telegramToken.hint": "Токенро аз @BotFather гузоред, то ба ин агент боти махсуси Telegram диҳед. Барои дастрасӣ тавассути боти умумӣ дар Танзимот → Ҳамгироӣ, бо пешванди фармони он, холӣ гузоред.", + "settings.agentui.field.whatsapp": "Дар WhatsApp ҷавоб додан", + "settings.agentui.field.whatsapp.hint": "API ғайрирасмии WhatsApp-ро истифода мебарад (тавассути waconector) — провайдерро интихоб кунед ва тафсилоти пайвастшавиро пур кунед. Провайдерони худмизбон ба сервери/контейнери алоҳидаи худ ниёз доранд.", + "settings.agentui.field.whatsapp.webhookUrl": "URL-и webhook — онро ба саҳифаи идоракунии провайдер часпонед", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL-и webhook, ки бояд аз тарафи провайдер танзим карда шавад, пас аз сабт дар ин ҷо намоён мешавад.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/th.ts b/packages/app/src/i18n/th.ts index 3bc4c655b412..bf89464dae53 100644 --- a/packages/app/src/i18n/th.ts +++ b/packages/app/src/i18n/th.ts @@ -852,6 +852,7 @@ export const dict = { "common.closeTab": "ปิดแท็บ", "common.dismiss": "ปิด", "common.requestFailed": "คำขอล้มเหลว", + "common.optional": "ไม่บังคับ", "common.moreOptions": "ตัวเลือกเพิ่มเติม", "common.learnMore": "เรียนรู้เพิ่มเติม", "common.rename": "เปลี่ยนชื่อ", @@ -1526,6 +1527,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "เปิดหน้านี้จากโปรเจกต์ที่เชื่อมต่อเพื่อให้เอเจนต์นี้มีบอท Telegram ของตัวเอง", + "settings.agentui.error.whatsappIncomplete": "เปิดหน้านี้จากโปรเจกต์ที่เชื่อมต่อ และกรอกทุกช่องที่จำเป็นสำหรับผู้ให้บริการ WhatsApp ที่เลือก", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1535,12 +1537,53 @@ export const dict = { "settings.agentui.ai.generate": "สร้าง", "settings.agentui.ai.generating": "กำลังสร้าง…", "settings.agentui.ai.toast.generated": "สร้างร่างแล้ว — ตรวจสอบก่อนบันทึก", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "โทเค็นบอท (ไม่บังคับ — เว้นว่างไว้เพื่อใช้บอทส่วนกลางร่วมกัน)", "settings.agentui.field.telegramToken.hint": "วางโทเค็นจาก @BotFather เพื่อให้เอเจนต์นี้มีบอท Telegram เฉพาะของตัวเอง เว้นว่างไว้เพื่อเข้าถึงผ่านบอทที่ใช้ร่วมกันในการตั้งค่า → การผสานรวม โดยใช้คำนำหน้าคำสั่งของมัน", + "settings.agentui.field.whatsapp": "ตอบกลับใน WhatsApp", + "settings.agentui.field.whatsapp.hint": "ใช้ WhatsApp API ที่ไม่เป็นทางการ (ผ่าน waconector) — เลือกผู้ให้บริการและกรอกรายละเอียดการเชื่อมต่อ ผู้ให้บริการแบบ self-hosted ต้องการเซิร์ฟเวอร์/คอนเทนเนอร์ของตนเองที่ทำงานแยกต่างหาก", + "settings.agentui.field.whatsapp.webhookUrl": "URL Webhook — วางลงในแดชบอร์ดของผู้ให้บริการ", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL Webhook ที่ต้องตั้งค่าฝั่งผู้ให้บริการจะปรากฏที่นี่หลังจากบันทึก", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/tk.ts b/packages/app/src/i18n/tk.ts index 7b1f3dfb65e4..7bf9c5efcd29 100644 --- a/packages/app/src/i18n/tk.ts +++ b/packages/app/src/i18n/tk.ts @@ -832,6 +832,7 @@ export const dict = { "common.dismiss": "Işden aýyrmak", "common.moreCountSuffix": " (+ {{count}} has köp)", "common.requestFailed": "Talap başa barmady", + "common.optional": "islege görä", "common.moreOptions": "Has köp wariant", "common.learnMore": "Has giňişleýin öwreniň", "common.rename": "Adyny üýtgetmek", @@ -1447,6 +1448,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Bu agenta öz Telegram botuny bermek üçin bu sahypany baglanan taslamadan açyň.", + "settings.agentui.error.whatsappIncomplete": "Bu sahypany baglanan taslamadan açyň we saýlanan WhatsApp üpjün edijisi üçin ähli zerur meýdanlary dolduryň.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1456,12 +1458,53 @@ export const dict = { "settings.agentui.ai.generate": "Döret", "settings.agentui.ai.generating": "Döredilýär…", "settings.agentui.ai.toast.generated": "Taslama döredildi — ýatda saklamazdan öň seredip görüň", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot tokeni (islege görä — global boty paýlaşmak üçin boş goýuň)", "settings.agentui.field.telegramToken.hint": "Bu agenta öz aýratyn Telegram botuny bermek üçin @BotFather-den token ýelmäň. Sazlamalar → Integrasiýalar bölümindäki paýlaşylan bot arkaly, onuň buýruk öňki goşulmasy bilen ýetmek üçin boş goýuň.", + "settings.agentui.field.whatsapp": "WhatsApp-da jogap ber", + "settings.agentui.field.whatsapp.hint": "Resmi bolmadyk WhatsApp API-ni ulanýar (waconector arkaly) — üpjün edijini saýlaň we baglanyşyk maglumatlaryny dolduryň. Öz-özüni ýerleşdirýän üpjün edijiler aýratyn işleýän öz serwerini/gapyny talap edýär.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — ony üpjün edijiniň paneline ýelmäň", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Üpjün edijiniň tarapynda sazlanmaly Webhook URL ýatda saklanandan soň şu ýerde görkezilýär.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/tr.ts b/packages/app/src/i18n/tr.ts index 14d3ba142645..ed72f63c2e93 100644 --- a/packages/app/src/i18n/tr.ts +++ b/packages/app/src/i18n/tr.ts @@ -870,6 +870,7 @@ export const dict = { "common.closeTab": "Sekmeyi kapat", "common.dismiss": "Kapat", "common.requestFailed": "İstek başarısız", + "common.optional": "isteğe bağlı", "common.moreOptions": "Daha fazla seçenek", "common.learnMore": "Daha fazla bilgi", "common.rename": "Yeniden adlandır", @@ -1548,6 +1549,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Bu ajana kendi Telegram botunu vermek için bu sayfayı bağlı bir projeden açın.", + "settings.agentui.error.whatsappIncomplete": "Bu sayfayı bağlı bir projeden açın ve seçilen WhatsApp sağlayıcısı için tüm gerekli alanları doldurun.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1557,12 +1559,53 @@ export const dict = { "settings.agentui.ai.generate": "Oluştur", "settings.agentui.ai.generating": "Oluşturuluyor…", "settings.agentui.ai.toast.generated": "Taslak oluşturuldu — kaydetmeden önce inceleyin", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot tokeni (isteğe bağlı — genel botu paylaşmak için boş bırakın)", "settings.agentui.field.telegramToken.hint": "Bu ajana kendine özel bir Telegram botu vermek için @BotFather'dan bir token yapıştırın. Boş bırakırsanız, Ayarlar → Entegrasyonlar bölümündeki paylaşılan bot üzerinden, komut önekini kullanarak erişilir.", + "settings.agentui.field.whatsapp": "WhatsApp'ta yanıtla", + "settings.agentui.field.whatsapp.hint": "Resmi olmayan bir WhatsApp API'si kullanır (waconector üzerinden) — bir sağlayıcı seçin ve bağlantı bilgilerini doldurun. Kendi kendine barındırılan sağlayıcılar, ayrı çalışan kendi sunucusuna/konteynerine ihtiyaç duyar.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL'si — sağlayıcının panosuna yapıştırın", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Sağlayıcı tarafında yapılandırılacak Webhook URL'si kaydettikten sonra burada görünür.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/uk.ts b/packages/app/src/i18n/uk.ts index 4f75bac5dc00..6658a33f6f5f 100644 --- a/packages/app/src/i18n/uk.ts +++ b/packages/app/src/i18n/uk.ts @@ -919,6 +919,7 @@ export const dict = { "common.dismiss": "Відхилити", "common.moreCountSuffix": " (ще {{count}})", "common.requestFailed": "Запит не виконано", + "common.optional": "необов'язково", "common.moreOptions": "Більше параметрів", "common.learnMore": "Дізнатися більше", "common.rename": "Перейменувати", @@ -1555,6 +1556,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Відкрийте цю сторінку з підключеного проєкту, щоб надати цьому агенту власного Telegram-бота.", + "settings.agentui.error.whatsappIncomplete": "Відкрийте цю сторінку з підключеного проєкту та заповніть усі обов'язкові поля для обраного постачальника WhatsApp.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1564,12 +1566,53 @@ export const dict = { "settings.agentui.ai.generate": "Згенерувати", "settings.agentui.ai.generating": "Генерування…", "settings.agentui.ai.toast.generated": "Чернетку створено — перегляньте перед збереженням", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Токен бота (необов'язково — залиште порожнім, щоб використовувати спільного бота)", "settings.agentui.field.telegramToken.hint": "Вставте токен від @BotFather, щоб надати цьому агенту власного виділеного Telegram-бота. Залиште порожнім, щоб отримати доступ через спільного бота в Налаштування → Інтеграції, за допомогою його командного префікса.", + "settings.agentui.field.whatsapp": "Відповідати в WhatsApp", + "settings.agentui.field.whatsapp.hint": "Використовує неофіційний WhatsApp API (через waconector) — оберіть постачальника та заповніть дані підключення. Постачальники з самостійним хостингом потребують власного, окремо запущеного сервера/контейнера.", + "settings.agentui.field.whatsapp.webhookUrl": "URL вебхука — вставте його в панель постачальника", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL вебхука, який потрібно налаштувати у постачальника, з'явиться тут після збереження.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/ur.ts b/packages/app/src/i18n/ur.ts index 35b1a0d26b7d..8bca80e0233d 100644 --- a/packages/app/src/i18n/ur.ts +++ b/packages/app/src/i18n/ur.ts @@ -843,6 +843,7 @@ export const dict = { "common.dismiss": "نظر انداز کریں", "common.moreCountSuffix": " (+{{count}} مزید)", "common.requestFailed": "درخواست ناکام ہوگئی", + "common.optional": "اختیاری", "common.moreOptions": "مزید اختیارات", "common.learnMore": "مزید جانیں", "common.rename": "نام تبدیل کریں۔", @@ -1452,6 +1453,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "اس ایجنٹ کو اپنا ٹیلیگرام بوٹ دینے کے لیے منسلک پراجیکٹ سے یہ صفحہ کھولیں۔", + "settings.agentui.error.whatsappIncomplete": "منسلک پراجیکٹ سے یہ صفحہ کھولیں اور منتخب کردہ WhatsApp فراہم کنندہ کے لیے تمام مطلوبہ فیلڈز پُر کریں۔", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1461,12 +1463,53 @@ export const dict = { "settings.agentui.ai.generate": "تخلیق کریں", "settings.agentui.ai.generating": "تخلیق ہو رہا ہے…", "settings.agentui.ai.toast.generated": "مسودہ تیار ہو گیا — محفوظ کرنے سے پہلے جائزہ لیں", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "بوٹ ٹوکن (اختیاری — عالمی بوٹ کا اشتراک کرنے کے لیے خالی چھوڑ دیں)", "settings.agentui.field.telegramToken.hint": "اس ایجنٹ کو اپنا مخصوص ٹیلیگرام بوٹ دینے کے لیے @BotFather سے ٹوکن پیسٹ کریں۔ ترتیبات ← انضمام میں مشترکہ بوٹ کے ذریعے، اس کے کمانڈ ٹرگر کا استعمال کرتے ہوئے رسائی کے لیے خالی چھوڑ دیں۔", + "settings.agentui.field.whatsapp": "WhatsApp پر جواب دیں", + "settings.agentui.field.whatsapp.hint": "ایک غیر سرکاری WhatsApp API استعمال کرتا ہے (waconector کے ذریعے) — ایک فراہم کنندہ منتخب کریں اور کنکشن کی تفصیلات پُر کریں۔ خود میزبان فراہم کنندگان کو الگ سے چلنے والا اپنا سرور/کنٹینر درکار ہوتا ہے۔", + "settings.agentui.field.whatsapp.webhookUrl": "ویب ہک URL — اسے فراہم کنندہ کے ڈیش بورڈ میں پیسٹ کریں", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "فراہم کنندہ کی طرف سے ترتیب دیا جانے والا ویب ہک URL محفوظ کرنے کے بعد یہاں ظاہر ہوتا ہے۔", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/uz.ts b/packages/app/src/i18n/uz.ts index 2431b7fb6cfc..ace4c20272a8 100644 --- a/packages/app/src/i18n/uz.ts +++ b/packages/app/src/i18n/uz.ts @@ -838,6 +838,7 @@ export const dict = { "common.dismiss": "Rad etish", "common.moreCountSuffix": " (+{{count}} ko'proq)", "common.requestFailed": "Soʻrov bajarilmadi", + "common.optional": "ixtiyoriy", "common.moreOptions": "Boshqa variantlar", "common.learnMore": "Batafsil maʼlumot", "common.rename": "Nomini o'zgartirish", @@ -1459,6 +1460,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Bu agentga o'zining Telegram botini berish uchun ulangan loyihadan bu sahifani oching.", + "settings.agentui.error.whatsappIncomplete": "Bu sahifani ulangan loyihadan oching va tanlangan WhatsApp provayderi uchun barcha talab qilinadigan maydonlarni to'ldiring.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1468,12 +1470,53 @@ export const dict = { "settings.agentui.ai.generate": "Yaratish", "settings.agentui.ai.generating": "Yaratilmoqda…", "settings.agentui.ai.toast.generated": "Qoralama yaratildi — saqlashdan oldin ko'rib chiqing", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Bot tokeni (ixtiyoriy — global botni ulashish uchun bo'sh qoldiring)", "settings.agentui.field.telegramToken.hint": "Bu agentga o'zining maxsus Telegram botini berish uchun @BotFather'dan tokenni joylashtiring. Sozlamalar → Integratsiyalar bo'limidagi umumiy bot orqali, uning buyruq prefiksi bilan kirish uchun bo'sh qoldiring.", + "settings.agentui.field.whatsapp": "WhatsApp'da javob berish", + "settings.agentui.field.whatsapp.hint": "Norasmiy WhatsApp API-dan foydalanadi (waconector orqali) — provayderni tanlang va ulanish tafsilotlarini to'ldiring. O'z-o'zini joylashtiruvchi provayderlar alohida ishlaydigan o'z serveri/konteynerini talab qiladi.", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — uni provayder boshqaruv paneliga joylashtiring", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "Provayder tomonida sozlanishi kerak bo'lgan Webhook URL saqlangandan keyin shu yerda ko'rinadi.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/vi.ts b/packages/app/src/i18n/vi.ts index b0c36acf56c1..330538fcbc9d 100644 --- a/packages/app/src/i18n/vi.ts +++ b/packages/app/src/i18n/vi.ts @@ -843,6 +843,7 @@ export const dict = { "common.dismiss": "Bỏ qua", "common.moreCountSuffix": " (+{{count}} thêm)", "common.requestFailed": "Không thực hiện được yêu cầu", + "common.optional": "tùy chọn", "common.moreOptions": "Nhiều lựa chọn hơn", "common.learnMore": "Tìm hiểu thêm", "common.rename": "Đổi tên", @@ -1457,6 +1458,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "Mở trang này từ một dự án đã kết nối để cung cấp cho tác nhân này bot Telegram riêng.", + "settings.agentui.error.whatsappIncomplete": "Mở trang này từ một dự án đã kết nối và điền tất cả các trường bắt buộc cho nhà cung cấp WhatsApp đã chọn.", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1466,12 +1468,53 @@ export const dict = { "settings.agentui.ai.generate": "Tạo", "settings.agentui.ai.generating": "Đang tạo…", "settings.agentui.ai.toast.generated": "Đã tạo bản nháp — hãy xem lại trước khi lưu", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "Token bot (tùy chọn — để trống để dùng chung bot toàn cục)", "settings.agentui.field.telegramToken.hint": "Dán token từ @BotFather để cung cấp cho tác nhân này bot Telegram chuyên dụng riêng. Để trống để truy cập qua bot dùng chung trong Cài đặt → Tích hợp, bằng tiền tố lệnh của nó.", + "settings.agentui.field.whatsapp": "Trả lời trên WhatsApp", + "settings.agentui.field.whatsapp.hint": "Sử dụng API WhatsApp không chính thức (thông qua waconector) — chọn nhà cung cấp và điền chi tiết kết nối. Các nhà cung cấp tự lưu trữ cần máy chủ/container riêng chạy tách biệt.", + "settings.agentui.field.whatsapp.webhookUrl": "URL webhook — dán nó vào bảng điều khiển của nhà cung cấp", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "URL webhook cần cấu hình ở phía nhà cung cấp sẽ xuất hiện ở đây sau khi bạn lưu.", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/zh.ts b/packages/app/src/i18n/zh.ts index c015666a663a..e32ec2214d3b 100644 --- a/packages/app/src/i18n/zh.ts +++ b/packages/app/src/i18n/zh.ts @@ -848,6 +848,7 @@ export const dict = { "common.closeTab": "关闭标签页", "common.dismiss": "忽略", "common.requestFailed": "请求失败", + "common.optional": "可选", "common.moreOptions": "更多选项", "common.learnMore": "了解更多", "common.rename": "重命名", @@ -1515,6 +1516,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "从已连接的项目打开此页面,为该代理配置专属的 Telegram 机器人。", + "settings.agentui.error.whatsappIncomplete": "从已连接的项目打开此页面,并填写所选 WhatsApp 提供商的所有必填字段。", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1524,12 +1526,53 @@ export const dict = { "settings.agentui.ai.generate": "生成", "settings.agentui.ai.generating": "生成中…", "settings.agentui.ai.toast.generated": "草稿已生成 — 保存前请检查", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "机器人令牌(可选 — 留空以共用全局机器人)", "settings.agentui.field.telegramToken.hint": "粘贴来自 @BotFather 的令牌,为该代理配置专属的 Telegram 机器人。留空则通过设置 → 集成中的共用机器人、使用其命令前缀来访问。", + "settings.agentui.field.whatsapp": "在 WhatsApp 上回复", + "settings.agentui.field.whatsapp.hint": "使用非官方 WhatsApp API(通过 waconector)— 选择提供商并填写连接详情。自托管提供商需要单独运行自己的服务器/容器;这里只是连接到它。", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — 将其粘贴到提供商的控制面板中", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "保存后,需要在提供商端配置的 Webhook URL 会显示在此处。", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/i18n/zht.ts b/packages/app/src/i18n/zht.ts index d3ca9d377bf4..1ed0aa70ac6f 100644 --- a/packages/app/src/i18n/zht.ts +++ b/packages/app/src/i18n/zht.ts @@ -845,6 +845,7 @@ export const dict = { "common.closeTab": "關閉分頁", "common.dismiss": "忽略", "common.requestFailed": "要求失敗", + "common.optional": "選填", "common.moreOptions": "更多選項", "common.learnMore": "深入了解", "common.rename": "重新命名", @@ -1511,6 +1512,7 @@ export const dict = { "settings.agentui.empty": "No agents yet.", // TODO: translate (auto-filled from en) "settings.agentui.error.incomplete": "Give the agent a name and pick a model.", // TODO: translate (auto-filled from en) "settings.agentui.error.telegramNeedsProject": "從已連接的專案開啟此頁面,為該代理設定專屬的 Telegram 機器人。", + "settings.agentui.error.whatsappIncomplete": "從已連接的專案開啟此頁面,並填寫所選 WhatsApp 供應商的所有必填欄位。", "settings.agentui.toast.saved": "Agent saved", // TODO: translate (auto-filled from en) "settings.agentui.dialog.addTitle": "Create agent", // TODO: translate (auto-filled from en) "settings.agentui.dialog.editTitle": "Edit agent", // TODO: translate (auto-filled from en) @@ -1520,12 +1522,53 @@ export const dict = { "settings.agentui.ai.generate": "生成", "settings.agentui.ai.generating": "生成中…", "settings.agentui.ai.toast.generated": "草稿已生成 — 儲存前請檢查", + "settings.agentui.tabs.general": "General", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.channels": "Channels", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.tools": "Tools", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.knowledge": "Knowledge", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers": "MCP servers", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.hint": "Let this agent call tools from the MCP servers below, connected to the same project as its channels. Off by default — agents are conversational-only until you turn one on.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.empty": "No MCP servers configured for this project yet. Add one in Settings → MCP first.", // TODO: translate (auto-filled from en) + "settings.agentui.field.mcpServers.noDirectory": "Open a project first to see its MCP servers.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.providerLink": "Open {{provider}} dashboard →", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.fetch": "Fetch sessions", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.empty": "No sessions found for this API key.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaSessions.label": "WhatsApp sessions (select one or more)", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.label": "Groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.hint": "Direct messages are always answered. Check any groups the agent should also answer in — groups left unchecked are ignored.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.fetch": "Fetch groups", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.loading": "Fetching…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.izapiaGroups.empty": "No groups found for the selected sessions.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.hint": "Simplest option if you already have Tailscale running on this machine and the provider's server: use this machine's Tailscale IP directly, no tunnel process needed.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.use": "Use Tailscale IP", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.detecting": "Detecting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.tailscale.notFound": "No Tailscale IP found. Is Tailscale installed and running?", // TODO: translate (auto-filled from en) +"settings.agentui.field.whatsapp.tunnel.hint": "This server's URL is local (127.0.0.1/localhost) — the provider can't call it back to deliver messages. Start a public tunnel so it can.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.start": "Start public tunnel", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.starting": "Starting…", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.active": "Public tunnel active: {{url}} — the webhook URL below now uses it.", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.tunnel.error": "Couldn't start the tunnel. Is cloudflared installed?", // TODO: translate (auto-filled from en) + "settings.agentui.tabs.audit": "Audit", // TODO: translate (auto-filled from en) + "settings.agentui.audit.title": "Message log", // TODO: translate (auto-filled from en) + "settings.agentui.audit.refresh": "Refresh", // TODO: translate (auto-filled from en) + "settings.agentui.audit.loading": "Loading…", // TODO: translate (auto-filled from en) + "settings.agentui.audit.needsSave": "Save the agent first to see its message log.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.empty": "No messages logged yet.", // TODO: translate (auto-filled from en) + "settings.agentui.audit.blocked": "Blocked", // TODO: translate (auto-filled from en) + "settings.agentui.audit.incoming": "Received", // TODO: translate (auto-filled from en) + "settings.agentui.audit.outgoing": "Replied", // TODO: translate (auto-filled from en) "settings.agentui.field.name": "Name", // TODO: translate (auto-filled from en) "settings.agentui.field.personality": "Personality", // TODO: translate (auto-filled from en) "settings.agentui.field.model": "Model", // TODO: translate (auto-filled from en) "settings.agentui.field.telegram": "Reply on Telegram", // TODO: translate (auto-filled from en) "settings.agentui.field.telegramToken.placeholder": "機器人權杖(選填 — 留空以共用全域機器人)", "settings.agentui.field.telegramToken.hint": "貼上來自 @BotFather 的權杖,為該代理設定專屬的 Telegram 機器人。留空則透過設定 → 整合中的共用機器人、使用其指令前綴來存取。", + "settings.agentui.field.whatsapp": "在 WhatsApp 上回覆", + "settings.agentui.field.whatsapp.hint": "使用非官方 WhatsApp API(透過 waconector)— 選擇供應商並填寫連線詳情。自架供應商需要單獨執行自己的伺服器/容器;這裡只是連線到它。", + "settings.agentui.field.whatsapp.webhookUrl": "Webhook URL — 將其貼到供應商的控制台中", + "settings.agentui.field.whatsapp.webhookSecret": "Webhook secret — some providers (e.g. izapia) ask for this separately", // TODO: translate (auto-filled from en) + "settings.agentui.field.whatsapp.webhookAfterSave": "儲存後,需要在供應商端設定的 Webhook URL 會顯示在此處。", "settings.agentui.field.commandTriggers": "Command triggers (space-separated, e.g. ! #)", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrails": "Guardrails", // TODO: translate (auto-filled from en) "settings.agentui.field.guardrailsLevel": "Guardrails level", // TODO: translate (auto-filled from en) diff --git a/packages/app/src/pages/agentui-audit.tsx b/packages/app/src/pages/agentui-audit.tsx new file mode 100644 index 000000000000..ee36784cd86a --- /dev/null +++ b/packages/app/src/pages/agentui-audit.tsx @@ -0,0 +1,180 @@ +import { createMemo, createResource, createSignal, For, Show, type Component } from "solid-js" +import { useNavigate, useParams } from "@solidjs/router" +import { ScrollView } from "@opencode-ai/ui/scroll-view" +import { ButtonV2 } from "@opencode-ai/ui/v2/button-v2" +import { IconButtonV2 } from "@opencode-ai/ui/v2/icon-button-v2" +import { Icon as IconV2 } from "@opencode-ai/ui/v2/icon" +import type { AgentUiAuditEntry } from "@opencode-ai/sdk/v2/types" +import { useLanguage } from "@/context/language" +import { useServerSDK } from "@/context/server-sdk" +import "@/components/settings-v2/settings-v2.css" + +type Contact = { + chatKey: string + channel: AgentUiAuditEntry["channel"] + entries: AgentUiAuditEntry[] + lastTimestamp: number + lastPreview: string +} + +function groupByContact(entries: AgentUiAuditEntry[]): Contact[] { + const byKey = new Map() + for (const entry of entries) { + const key = `${entry.channel}\0${entry.chatKey}` + const existing = byKey.get(key) + if (existing) { + existing.entries.push(entry) + if (entry.timestamp > existing.lastTimestamp) { + existing.lastTimestamp = entry.timestamp + existing.lastPreview = entry.outgoing || entry.incoming + } + continue + } + byKey.set(key, { + chatKey: entry.chatKey, + channel: entry.channel, + entries: [entry], + lastTimestamp: entry.timestamp, + lastPreview: entry.outgoing || entry.incoming, + }) + } + return [...byKey.values()].sort((a, b) => b.lastTimestamp - a.lastTimestamp) +} + +export const AgentUIAuditPage: Component = () => { + const navigate = useNavigate() + const params = useParams<{ id: string }>() + const language = useLanguage() + const serverSDK = useServerSDK() + + const [selected, setSelected] = createSignal(undefined) + + const [agent] = createResource( + () => params.id, + async (id) => { + const result = await serverSDK().client.agentui.get({ id }) + return result.data + }, + ) + + const [audit, { refetch }] = createResource( + () => params.id, + async (id) => { + const result = await serverSDK().client.agentui.audit({ id }) + return result.data ?? [] + }, + ) + + const contacts = createMemo(() => groupByContact(audit() ?? [])) + const selectedContact = createMemo(() => contacts().find((c) => `${c.channel}\0${c.chatKey}` === selected())) + const selectedThread = createMemo(() => [...(selectedContact()?.entries ?? [])].sort((a, b) => a.timestamp - b.timestamp)) + + return ( +
+
+
+
+
+ } + aria-label={language.t("common.goBack")} + onClick={() => (selected() ? setSelected(undefined) : navigate("/agentui"))} + /> +

+ {selectedContact() + ? selectedContact()!.chatKey + : `${language.t("settings.agentui.audit.title")} · ${agent()?.name ?? ""}`} +

+
+ void refetch()}> + {audit.loading ? language.t("settings.agentui.audit.loading") : language.t("settings.agentui.audit.refresh")} + +
+
+ + + + +

{language.t("settings.agentui.audit.empty")}

+
+
+ + {(contact) => ( + + )} + +
+
+ } + > +
+ + {(entry) => ( +
+
+ + {new Date(entry.timestamp).toLocaleString()} + +

{entry.incoming}

+
+ + + {language.t("settings.agentui.audit.blocked")} + + + } + > +
+

{entry.outgoing}

+ + + {language.t("settings.agentui.audit.blocked")} + + +
+ +
+ )} +
+
+ + +
+
+ ) +} diff --git a/packages/app/src/pages/agentui-form.tsx b/packages/app/src/pages/agentui-form.tsx index 7d983a4b9d6f..57c6c8a46dd6 100644 --- a/packages/app/src/pages/agentui-form.tsx +++ b/packages/app/src/pages/agentui-form.tsx @@ -10,6 +10,7 @@ import { TextInputV2 } from "@opencode-ai/ui/v2/text-input-v2" import { TextareaV2 } from "@opencode-ai/ui/v2/textarea-v2" import { Switch } from "@opencode-ai/ui/v2/switch-v2" import { TooltipV2 } from "@opencode-ai/ui/v2/tooltip-v2" +import { TabsV2 } from "@opencode-ai/ui/v2/tabs-v2" import { useDialog } from "@opencode-ai/ui/context/dialog" import { useLanguage } from "@/context/language" import { useServerSDK } from "@/context/server-sdk" @@ -20,8 +21,25 @@ import { createHomeController } from "@/pages/home/home-controller" import { showToast } from "@/utils/toast" import { ModelPickerV2 } from "@/components/batuta/model-picker-v2" import { DialogAgentUISandbox } from "@/components/settings-v2/dialog-agentui-sandbox" +import { + WHATSAPP_PROVIDER_FIELDS, + WHATSAPP_PROVIDER_LABELS, + WHATSAPP_PROVIDER_LINKS, + type WhatsAppProvider, +} from "@/components/settings-v2/whatsapp-providers" import "@/components/settings-v2/settings-v2.css" +// Module-level (not component state) so it survives remounting the form — +// reopening "Editar agente" for the same izapia agent used to re-hit +// whatsapp.izapiaSessions/izapiaGroups every single time via the auto-load +// effect below. Each visit is a handful of HTTP calls against izapia's own +// account-wide rate limit; enough repeat visits during a session exhausted +// that budget and made the *actual* reply-send fail too (see whatsapp/ +// index.ts's sendText retry). Caching by apiKey (and by apiKey+session set +// for groups) means only the first visit per key pays that cost. +const izapiaSessionsCache = new Map() +const izapiaGroupsCache = new Map() + type RagSource = { id: string; kind: "text" | "url"; label: string; value: string } type AgentUIFormState = { id: string @@ -34,6 +52,13 @@ type AgentUIFormState = { guardrailsLevel: "basic" | "strict" telegram: boolean telegramToken: string + whatsapp: boolean + whatsappProvider: WhatsAppProvider + whatsappConfig: Record + whatsappSessionIds: string[] + whatsappAllowedGroups: string[] + whatsappWebhookSecret: string + mcpServers: string[] enabled: boolean } @@ -49,6 +74,13 @@ function emptyForm(): AgentUIFormState { guardrailsLevel: "basic", telegram: false, telegramToken: "", + whatsapp: false, + whatsappProvider: "izapia", + whatsappConfig: {}, + whatsappSessionIds: [], + whatsappAllowedGroups: [], + whatsappWebhookSecret: "", + mcpServers: [], enabled: true, } } @@ -81,6 +113,17 @@ export function AgentUIFormPage() { return (result.data ?? []).map((c) => ({ id: c.id, name: c.name })) }) + // MCP servers this agent could be given tool access to — scoped to + // whichever connected project's config the agent's channels/sandbox run + // against (same `directory` model.ts and the WhatsApp/Telegram bindings + // already use). Re-fetches whenever the directory changes since MCP + // config is per-project, not global. + const [mcpServers] = createResource(directory, async (dir) => { + if (!dir) return [] + const result = await serverSDK().client.mcp.status({ directory: dir }) + return Object.keys(result.data ?? {}) + }) + const [existing] = createResource( () => params.id, async (id) => { @@ -109,14 +152,129 @@ export function AgentUIFormPage() { guardrailsLevel: agent.guardrails.level, telegram: agent.channels.some((c) => c.type === "telegram"), telegramToken: agent.channels.find((c) => c.type === "telegram")?.token ?? "", + whatsapp: agent.channels.some((c) => c.type === "whatsapp"), + whatsappProvider: (agent.channels.find((c) => c.type === "whatsapp")?.provider as WhatsAppProvider) ?? "waha", + whatsappConfig: agent.channels.find((c) => c.type === "whatsapp")?.config ?? {}, + whatsappSessionIds: [...(agent.channels.find((c) => c.type === "whatsapp")?.sessionIds ?? [])], + whatsappAllowedGroups: [...(agent.channels.find((c) => c.type === "whatsapp")?.allowedGroups ?? [])], + whatsappWebhookSecret: agent.channels.find((c) => c.type === "whatsapp")?.webhookSecret ?? "", + mcpServers: agent.mcpServers ?? [], enabled: agent.enabled !== false, }) }) + // Auto-load the izapia session/group pickers on edit — without this, the + // lists start empty (see izapiaSessions/izapiaGroups below) even though + // form.whatsappSessionIds/whatsappAllowedGroups already hold the saved + // selection, so reopening an agent for editing looked like every + // session/group checkbox had to be picked again from scratch. + createEffect(() => { + const agent = existing() + if (!agent || !isEdit) return + const channel = agent.channels.find((c) => c.type === "whatsapp") + if (channel?.type !== "whatsapp" || channel.provider !== "izapia") return + const apiKey = channel.config.apiKey?.trim() + if (!apiKey) return + void fetchIzapiaSessions().then(() => { + if (form.whatsappSessionIds.length > 0) void fetchIzapiaGroups() + }) + }) + const addRagSource = () => setForm("ragSources", (list) => [...list, { id: crypto.randomUUID(), kind: "text", label: "", value: "" }]) const removeRagSource = (id: string) => setForm("ragSources", (list) => list.filter((s) => s.id !== id)) + const toggleMcpServer = (name: string, checked: boolean) => + setForm("mcpServers", (list) => (checked ? [...list, name] : list.filter((item) => item !== name))) + + // izapia-only: fetches the tenant's existing WhatsApp sessions for the + // API key already typed in, so the person can pick one instead of going + // to find and paste a sid by hand from the izapia dashboard. + const [izapiaSessions, setIzapiaSessions] = createSignal< + { id: string; name?: string; status: string; jid?: string }[] + >([]) + const [izapiaSessionsLoading, setIzapiaSessionsLoading] = createSignal(false) + const [izapiaSessionsError, setIzapiaSessionsError] = createSignal() + + const fetchIzapiaSessions = async (options?: { force?: boolean }) => { + const apiKey = form.whatsappConfig.apiKey?.trim() + if (!apiKey || izapiaSessionsLoading()) return + if (!options?.force) { + const cached = izapiaSessionsCache.get(apiKey) + if (cached) { + setIzapiaSessions(cached) + return + } + } + setIzapiaSessionsError(undefined) + setIzapiaSessionsLoading(true) + try { + const result = await serverSDK().client.whatsapp.izapiaSessions({ apiKey }) + izapiaSessionsCache.set(apiKey, result.data ?? []) + setIzapiaSessions(result.data ?? []) + if (!result.data?.length) setIzapiaSessionsError(language.t("settings.agentui.field.whatsapp.izapiaSessions.empty")) + } catch (cause) { + setIzapiaSessionsError(cause instanceof Error ? cause.message : String(cause)) + } finally { + setIzapiaSessionsLoading(false) + } + } + + const toggleIzapiaSession = (id: string, checked: boolean) => { + setForm("whatsappSessionIds", (list) => (checked ? [...list, id] : list.filter((item) => item !== id))) + // Group access was scoped to the sessions previously selected — drop + // anything that no longer belongs to any selected session once the + // session set changes, rather than silently keeping a stale allow-list. + setIzapiaGroups([]) + setIzapiaGroupsError(undefined) + setForm("whatsappAllowedGroups", []) + } + + // izapia-only, second step: once at least one session is picked, fetches + // the groups those sessions belong to so the person can check exactly + // which ones the agent should be allowed to answer in (see + // ConfigAgentUIV1.WhatsAppChannelBinding.allowedGroups — direct messages + // are always answered regardless of this list). + const [izapiaGroups, setIzapiaGroups] = createSignal< + { id: string; subject: string; sessionId: string; participantCount: number }[] + >([]) + const [izapiaGroupsLoading, setIzapiaGroupsLoading] = createSignal(false) + const [izapiaGroupsError, setIzapiaGroupsError] = createSignal() + + const fetchIzapiaGroups = async (options?: { force?: boolean }) => { + const apiKey = form.whatsappConfig.apiKey?.trim() + if (!apiKey || form.whatsappSessionIds.length === 0 || izapiaGroupsLoading()) return + const cacheKey = `${apiKey}:${[...form.whatsappSessionIds].sort().join(",")}` + if (!options?.force) { + const cached = izapiaGroupsCache.get(cacheKey) + if (cached) { + setIzapiaGroups(cached) + return + } + } + setIzapiaGroupsError(undefined) + setIzapiaGroupsLoading(true) + try { + const result = await serverSDK().client.whatsapp.izapiaGroups({ apiKey, sids: form.whatsappSessionIds }) + izapiaGroupsCache.set(cacheKey, result.data ?? []) + setIzapiaGroups(result.data ?? []) + if (!result.data?.length) setIzapiaGroupsError(language.t("settings.agentui.field.whatsapp.izapiaGroups.empty")) + } catch (cause) { + setIzapiaGroupsError(cause instanceof Error ? cause.message : String(cause)) + } finally { + setIzapiaGroupsLoading(false) + } + } + + const toggleIzapiaGroup = (id: string, checked: boolean) => + setForm("whatsappAllowedGroups", (list) => (checked ? [...list, id] : list.filter((item) => item !== id))) + + // Audit log: one row per real turn (incoming message + the agent's + // reply), across every channel — see AgentUI.Service.logAudit. A dedicated + // full-page view (AgentUIAuditPage, /agentui/:id/audit), not a tab here — + // an agent can have hundreds of distinct conversations, which needs a + // contact-list-then-thread layout this narrow sidebar tab isn't built for. + const [saving, setSaving] = createSignal(false) const [error, setError] = createSignal() @@ -162,12 +320,45 @@ export function AgentUIFormPage() { setError(language.t("settings.agentui.error.telegramNeedsProject")) return } + const whatsappFields = WHATSAPP_PROVIDER_FIELDS[form.whatsappProvider] + const whatsappMissingField = form.whatsapp && whatsappFields.some((f) => f.required && !form.whatsappConfig[f.key]?.trim()) + const whatsappMissingSession = + form.whatsapp && form.whatsappProvider === "izapia" && form.whatsappSessionIds.length === 0 + if (form.whatsapp && (!directory() || whatsappMissingField || whatsappMissingSession)) { + setError(language.t("settings.agentui.error.whatsappIncomplete")) + return + } setError(undefined) setSaving(true) const triggers = form.commandTriggers .split(/\s+/) .map((t) => t.trim()) .filter(Boolean) + const channels: Array< + | { type: "telegram"; token?: string; directory?: string } + | { + type: "whatsapp" + provider: WhatsAppProvider + config: Record + sessionIds?: string[] + allowedGroups?: string[] + directory?: string + webhookSecret: string + } + > = [] + if (form.telegram) channels.push({ type: "telegram", token: ownBotToken || undefined, directory: ownBotToken ? directory() : undefined }) + const whatsappWebhookSecret = form.whatsappWebhookSecret || crypto.randomUUID() + if (form.whatsapp) { + channels.push({ + type: "whatsapp", + provider: form.whatsappProvider, + config: form.whatsappConfig, + sessionIds: form.whatsappProvider === "izapia" ? form.whatsappSessionIds : undefined, + allowedGroups: form.whatsappProvider === "izapia" ? form.whatsappAllowedGroups : undefined, + directory: directory(), + webhookSecret: whatsappWebhookSecret, + }) + } try { await serverSDK().client.agentui.add({ agentUiAgent: { @@ -175,15 +366,23 @@ export function AgentUIFormPage() { name: form.name, personality: form.personality, model: form.model, - channels: form.telegram - ? [{ type: "telegram", token: ownBotToken || undefined, directory: ownBotToken ? directory() : undefined }] - : [], + channels, commandTriggers: triggers, - ragSources: form.ragSources.filter((s) => s.label && s.value), + // Only `value` is actually required to be useful (it's the text/URL + // that gets fetched) — dropping a source just because its `label` + // was left blank silently threw away real content on save (a + // pasted URL with no title never made it past this filter, so it + // looked "saved" in the form but was gone after reloading). A + // missing label falls back to the value itself instead. + ragSources: form.ragSources + .filter((s) => s.value.trim()) + .map((s) => ({ ...s, label: s.label.trim() || s.value.trim() })), guardrails: { enabled: form.guardrailsEnabled, level: form.guardrailsLevel }, + mcpServers: form.mcpServers, enabled: form.enabled, }, }) + if (form.whatsapp) setForm("whatsappWebhookSecret", whatsappWebhookSecret) showToast({ variant: "success", icon: "circle-check", title: language.t("settings.agentui.toast.saved") }) setEverSaved(true) if (!isEdit) navigate(`/agentui/${form.id}/edit`, { replace: true }) @@ -206,6 +405,79 @@ export function AgentUIFormPage() { isEdit ? language.t("settings.agentui.form.title.edit") : language.t("settings.agentui.form.title.create"), ) + // server.url is the opencode API base the app itself talks to — for a + // desktop install that's 127.0.0.1/localhost, which no remote waconector + // provider can ever call back into. publicTunnelUrl (a cloudflared quick + // tunnel, see Tunnel.Service) stands in for it once started; the webhook + // link below prefers it whenever the raw server URL is a private/loopback + // address. + const PRIVATE_HOST_PATTERN = /^(127\.|10\.|192\.168\.|172\.(1[6-9]|2\d|3[01])\.|0\.0\.0\.0|localhost)/i + const isPrivateServerUrl = createMemo(() => { + try { + return PRIVATE_HOST_PATTERN.test(new URL(serverSDK().url).hostname) + } catch { + return false + } + }) + + const [publicTunnelUrl, setPublicTunnelUrl] = createSignal() + const [tunnelStarting, setTunnelStarting] = createSignal(false) + const [tunnelError, setTunnelError] = createSignal() + + const startPublicTunnel = async () => { + if (tunnelStarting()) return + setTunnelError(undefined) + setTunnelStarting(true) + try { + const port = Number(new URL(serverSDK().url).port) || 80 + const result = await serverSDK().client.tunnel.start({ port }) + if (result.data?.url) setPublicTunnelUrl(result.data.url) + else setTunnelError(language.t("settings.agentui.field.whatsapp.tunnel.error")) + } catch (cause) { + setTunnelError(cause instanceof Error ? cause.message : String(cause)) + } finally { + setTunnelStarting(false) + } + } + + // Simpler alternative to the cloudflared quick tunnel: if this machine + // already has Tailscale running (as our own izapia VPS setups do), the + // provider can reach this server directly over the tailnet at its + // 100.x.x.x address — no external process, no random URL that expires + // when the tunnel dies. Reuses publicTunnelUrl as the webhook base since + // both are just "however the provider reaches this server publicly". + const [tailscaleDetecting, setTailscaleDetecting] = createSignal(false) + const [tailscaleError, setTailscaleError] = createSignal() + + const useTailscaleIp = async () => { + if (tailscaleDetecting()) return + setTailscaleError(undefined) + setTailscaleDetecting(true) + try { + const port = Number(new URL(serverSDK().url).port) || 80 + const result = await serverSDK().client.tunnel.tailscale() + if (result.data?.available && result.data.ip) { + setPublicTunnelUrl(`http://${result.data.ip}:${port}`) + } else { + setTailscaleError(language.t("settings.agentui.field.whatsapp.tunnel.tailscale.notFound")) + } + } catch (cause) { + setTailscaleError(cause instanceof Error ? cause.message : String(cause)) + } finally { + setTailscaleDetecting(false) + } + } + + // Shown so the user can paste it into the selected provider's dashboard. + // Only meaningful once the agent has actually been saved with WhatsApp + // enabled (before that, there's no webhookSecret yet). + const whatsappWebhookUrl = createMemo(() => { + const secret = form.whatsappWebhookSecret + if (!secret) return undefined + const base = (publicTunnelUrl() ?? serverSDK().url).replace(/\/$/, "") + return `${base}/whatsapp/webhook/${form.id}/${secret}?directory=${encodeURIComponent(directory() ?? "")}` + }) + return (
- -
-
- - setForm("enabled", checked)} /> -
- -
- - setForm("model", value)} combos={combos() ?? []} /> -
- -
-
- - setForm("telegram", checked)} /> -
- - setForm("telegramToken", event.currentTarget.value)} - placeholder={language.t("settings.agentui.field.telegramToken.placeholder")} - /> -

{language.t("settings.agentui.field.telegramToken.hint")}

-
-
+
+ + + {language.t("settings.agentui.tabs.general")} + {language.t("settings.agentui.tabs.channels")} + {language.t("settings.agentui.tabs.tools")} + {language.t("settings.agentui.tabs.knowledge")} + -
- - setForm("commandTriggers", event.currentTarget.value)} - placeholder="! #" - /> -
- -
- - setForm("guardrailsEnabled", checked)} /> -
- -
- - -
-
+ + +
+
+ + setForm("enabled", checked)} /> +
-
- - - {(source, index) => ( -
- setForm("ragSources", index(), "label", event.currentTarget.value)} +
+ + setForm("model", value)} + combos={combos() ?? []} + directory={directory()} /> +
+ +
+ setForm("ragSources", index(), "value", event.currentTarget.value)} - /> - } - aria-label={language.t("common.remove")} - onClick={() => removeRagSource(source.id)} + value={form.commandTriggers} + onInput={(event) => setForm("commandTriggers", event.currentTarget.value)} + placeholder="! #" />
- )} - - - {language.t("settings.agentui.rag.add")} - -

{language.t("settings.agentui.rag.note")}

-
-
- + +
+ + setForm("guardrailsEnabled", checked)} /> +
+ +
+ + +
+
+
+
+ + +
+
+
+ + setForm("telegram", checked)} /> +
+ + setForm("telegramToken", event.currentTarget.value)} + placeholder={language.t("settings.agentui.field.telegramToken.placeholder")} + /> +

{language.t("settings.agentui.field.telegramToken.hint")}

+
+
+ +
+
+ + setForm("whatsapp", checked)} /> +
+ + + + {(url) => ( + + {language.t("settings.agentui.field.whatsapp.providerLink", { + provider: WHATSAPP_PROVIDER_LABELS[form.whatsappProvider], + })} + + )} + + + {(field) => ( + + setForm("whatsappConfig", (cfg) => ({ ...cfg, [field.key]: event.currentTarget.value })) + } + placeholder={field.label + (field.required ? "" : ` (${language.t("common.optional")})`)} + /> + )} + + + + void fetchIzapiaSessions({ force: true })} + > + {izapiaSessionsLoading() + ? language.t("settings.agentui.field.whatsapp.izapiaSessions.loading") + : language.t("settings.agentui.field.whatsapp.izapiaSessions.fetch")} + + + {izapiaSessionsError()} + + 0}> +
+ + {(session) => ( + + )} + +
+
+ + +

+ {language.t("settings.agentui.field.whatsapp.izapiaGroups.hint")} +

+ void fetchIzapiaGroups({ force: true })} + > + {izapiaGroupsLoading() + ? language.t("settings.agentui.field.whatsapp.izapiaGroups.loading") + : language.t("settings.agentui.field.whatsapp.izapiaGroups.fetch")} + + + {izapiaGroupsError()} + + 0}> +
+ + {(group) => ( + + )} + +
+
+
+

{language.t("settings.agentui.field.whatsapp.hint")}

+ +
+

+ {language.t("settings.agentui.field.whatsapp.tunnel.tailscale.hint")} +

+ void useTailscaleIp()} + > + {tailscaleDetecting() + ? language.t("settings.agentui.field.whatsapp.tunnel.tailscale.detecting") + : language.t("settings.agentui.field.whatsapp.tunnel.tailscale.use")} + + + {tailscaleError()} + +

+ {language.t("settings.agentui.field.whatsapp.tunnel.hint")} +

+ void startPublicTunnel()}> + {tunnelStarting() + ? language.t("settings.agentui.field.whatsapp.tunnel.starting") + : language.t("settings.agentui.field.whatsapp.tunnel.start")} + + + {tunnelError()} + +
+
+ +

+ {language.t("settings.agentui.field.whatsapp.tunnel.active", { url: publicTunnelUrl()! })} +

+
+ + {language.t("settings.agentui.field.whatsapp.webhookAfterSave")} +

+ } + > + {(url) => ( + <> +
+ + +
+
+ + +
+ + )} +
+
+
+
+
+ + +
+ +

{language.t("settings.agentui.field.mcpServers.hint")}

+ {language.t("common.loading")}

} + > + 0} + fallback={ +

+ {directory() + ? language.t("settings.agentui.field.mcpServers.empty") + : language.t("settings.agentui.field.mcpServers.noDirectory")} +

+ } + > + + {(name) => ( +
+ {name} + toggleMcpServer(name, checked)} + /> +
+ )} +
+
+
+
+
+ + +
+
+ + + {(source, index) => ( +
+ setForm("ragSources", index(), "label", event.currentTarget.value)} + /> + setForm("ragSources", index(), "value", event.currentTarget.value)} + /> + } + aria-label={language.t("common.remove")} + onClick={() => removeRagSource(source.id)} + /> +
+ )} +
+ + {language.t("settings.agentui.rag.add")} + +

{language.t("settings.agentui.rag.note")}

+
+
+
+ +
+
+
diff --git a/packages/core/src/v1/config/agentui.ts b/packages/core/src/v1/config/agentui.ts index 585e40bce60b..da1e5c065d02 100644 --- a/packages/core/src/v1/config/agentui.ts +++ b/packages/core/src/v1/config/agentui.ts @@ -2,10 +2,8 @@ export * as ConfigAgentUIV1 from "./agentui" import { Schema } from "effect" -export const ChannelBinding = Schema.Struct({ - type: Schema.Literals(["telegram"]).annotate({ - description: "Which channel this AgentUI listens/replies on. Only 'telegram' exists today — more (whatsapp, discord, ...) land as new Channel implementations without changing this shape.", - }), +export const TelegramChannelBinding = Schema.Struct({ + type: Schema.Literal("telegram"), // Per-agent bot token (from @BotFather) — when set, this agent gets its // own dedicated Telegram bot/poll loop that responds to every message // directly, no command-trigger prefix needed. When absent, the agent @@ -23,7 +21,72 @@ export const ChannelBinding = Schema.Struct({ directory: Schema.optional(Schema.String).annotate({ description: "Connected project directory this agent's dedicated bot operates against. Required alongside token.", }), -}).annotate({ identifier: "AgentUIChannelBinding" }) +}).annotate({ identifier: "AgentUITelegramChannelBinding" }) +export type TelegramChannelBinding = Schema.Schema.Type + +// The waconector package (https://alltomatos.github.io/waconector/) wraps 9 +// unofficial WhatsApp APIs behind one contract — some self-hosted (need a +// Docker container the user runs themselves), some SaaS (need only an API +// key). Every provider's real required fields differ (see +// packages/opencode/src/whatsapp/index.ts PROVIDER_FIELDS, sourced directly +// from each adapter's shipped .d.ts, not the docs site — which uses +// different factory names than the actual package). `config` is therefore +// untyped here on purpose: validating it against the right shape for the +// selected `provider` is WhatsApp.Service's job, at connect time. +export const WHATSAPP_PROVIDERS = [ + "waha", + "evolution", + "zapi", + "uazapi", + "whapi", + "wuzapi", + "quepasa", + "wppconnect", + "izapia", +] as const +export type WhatsAppProvider = (typeof WHATSAPP_PROVIDERS)[number] + +export const WhatsAppChannelBinding = Schema.Struct({ + type: Schema.Literal("whatsapp"), + provider: Schema.Literals(WHATSAPP_PROVIDERS).annotate({ + description: "Which unofficial WhatsApp API this channel connects through (see waconector).", + }), + config: Schema.Record(Schema.String, Schema.String).annotate({ + description: "Provider-specific connection fields (e.g. baseUrl+apiKey for WAHA, instanceId+token for Z-API). Shape depends on `provider`.", + }), + // izapia is multi-session per tenant (one API key, several WhatsApp + // numbers) — this agent can listen on more than one at once. Absent for + // single-session providers, which keep using `config.sid`/`config.session` + // instead. When present, it's the source of truth for which sessions this + // channel is bound to; `config.sid` (if still set from before this field + // existed) is ignored. + sessionIds: Schema.optional(Schema.mutable(Schema.Array(Schema.String))).annotate({ + description: "Session IDs this channel listens on, for providers with multiple sessions per tenant (izapia). Absent means single-session (see config.sid).", + }), + // Direct messages are always answered; a group is only answered if its + // JID is listed here. Empty/absent = groups off entirely (DMs only) — + // the safer default, since a bot answering in every group it's ever + // added to is rarely what someone wants. + allowedGroups: Schema.optional(Schema.mutable(Schema.Array(Schema.String))).annotate({ + description: "WhatsApp group JIDs this agent may respond in, in addition to direct messages. Empty/absent means direct messages only.", + }), + directory: Schema.optional(Schema.String).annotate({ + description: "Connected project directory this agent's WhatsApp channel operates against.", + }), + // Generated once, embedded in the webhook URL handed to the provider — + // this inbound endpoint is called by a third-party service (not our own + // authenticated client), so it can't go through the normal Authorization + // middleware; this secret is the only thing standing between it and the + // public internet. See WhatsApp.Service.handleWebhook. + webhookSecret: Schema.String.annotate({ + description: "Random per-channel secret embedded in the webhook URL — authenticates inbound webhook calls from the provider.", + }), +}).annotate({ identifier: "AgentUIWhatsAppChannelBinding" }) +export type WhatsAppChannelBinding = Schema.Schema.Type + +export const ChannelBinding = Schema.Union([TelegramChannelBinding, WhatsAppChannelBinding]).annotate({ + identifier: "AgentUIChannelBinding", +}) export type ChannelBinding = Schema.Schema.Type export const RagSource = Schema.Struct({ @@ -63,6 +126,15 @@ export const Agent = Schema.Struct({ description: "Knowledge sources this agent can retrieve from", }), guardrails: Guardrails, + // Names of MCP servers (as configured for `channels[].directory`/the + // sandbox `directory`) this agent's session is allowed to call tools + // from — matched by prefix against the sanitized tool names MCP.tools() + // produces (see McpCatalog.toolName/sanitize). Absent/empty means none: + // AgentUI sessions are conversational-only by default (see + // AgentUI.Service.sessionPermission), same as before this field existed. + mcpServers: Schema.optional(Schema.mutable(Schema.Array(Schema.String))).annotate({ + description: "Names of MCP servers this agent is allowed to call tools from. Empty/absent means none.", + }), // Absent/undefined means enabled — old configs saved before this field // existed must keep working exactly as before. Read via isEnabled() // below rather than this field directly. diff --git a/packages/opencode/package.json b/packages/opencode/package.json index 484ffaacc4ed..4c17187c90b7 100644 --- a/packages/opencode/package.json +++ b/packages/opencode/package.json @@ -115,6 +115,7 @@ "bonjour-service": "1.3.0", "bun-pty": "0.4.8", "chokidar": "4.0.3", + "waconector": "1.3.0", "cross-spawn": "catalog:", "decimal.js": "10.5.0", "diff": "catalog:", diff --git a/packages/opencode/src/agentui/index.ts b/packages/opencode/src/agentui/index.ts index a27f1eca8577..3f00085b6921 100644 --- a/packages/opencode/src/agentui/index.ts +++ b/packages/opencode/src/agentui/index.ts @@ -15,9 +15,11 @@ import { InstanceStore } from "@/project/instance-store" import { InstanceRef } from "@/effect/instance-ref" import { SessionID } from "@/session/schema" import { Provider } from "@/provider/provider" +import { Storage } from "@/storage/storage" import { Context, Effect, Layer, Schema } from "effect" import { jsonSchema, streamText, tool } from "ai" import { type LanguageModelV3 } from "@ai-sdk/provider" +import { McpCatalog } from "@/mcp/catalog" // Phase 1 of the AgentUI epic (#144) — CRUD only. No channel routing, RAG // retrieval, or guardrail enforcement yet (those are Phases 3-5); this just @@ -48,6 +50,25 @@ export interface GeneratedDraft { readonly guardrails: { enabled: boolean; level: "basic" | "strict" } } +// One row per real turn — the incoming message and the agent's reply +// together, not split into separate in/out entries — since what an +// auditor actually wants to see is "what came in, what went out", not +// reconstruct pairs from an interleaved log. Persisted via Storage.Service +// (global, not per-project — an agent's audit trail should survive +// switching which connected project its channel runs against) under +// ["agentui", "audit", ], capped to the most recent +// AUDIT_LOG_CAP turns per agent so this can't grow unbounded. +export const AuditEntry = Schema.Struct({ + id: Schema.String, + timestamp: Schema.Number, + channel: Schema.Literals(["whatsapp", "telegram", "sandbox"]), + chatKey: Schema.String, + incoming: Schema.String, + outgoing: Schema.String, + blocked: Schema.Boolean, +}) +export type AuditEntry = Schema.Schema.Type + // Same cheap/fast/reliable-at-tool-calling candidates Memory.Service tries // for its own one-shot structured extraction (see resolveModel there) — // generation here is a single tool call, not a conversation, so the exact @@ -93,8 +114,12 @@ export interface Interface { // 3. sessionPermission returns a restricted PermissionV1.Ruleset — // AgentUI sessions are conversational by default and get no shell/ // file access, regardless of guardrails.enabled, the same way Batuta's - // pipeline-chat sessions are scoped (see Batuta.Service). - readonly sessionPermission: () => PermissionV1.Ruleset + // pipeline-chat sessions are scoped (see Batuta.Service). `mcpServers` + // (an agent's configured allowlist, see ConfigAgentUIV1.Agent) adds one + // allow rule per server so its tool calls don't fall through to the + // default "ask" action — which would hang forever, since a channel + // dispatch has no human attached to answer a permission prompt. + readonly sessionPermission: (mcpServers?: readonly string[]) => PermissionV1.Ruleset // Resolves an agent's `model` field ("providerID/modelID" or // "combo:", same encoding ModelPickerV2 uses) to a concrete pair. // Shared by every channel (Telegram, the sandbox test chat below) so @@ -113,6 +138,26 @@ export interface Interface { message: string }) => Effect.Effect<{ reply: string; blocked: boolean }, AgentUINotFoundError> readonly resetSandbox: (id: string) => Effect.Effect + // Generalizes testMessage() beyond the fixed sandbox session: any real + // channel (WhatsApp today) that just needs "guardrail check -> hardened + // system prompt -> resolved model -> RAG -> one prompt call -> reply + // text", one independent session per (agent, chatKey) pair, without + // Telegram's own richer background-task/typing-indicator machinery. + readonly dispatchChannelMessage: (input: { + id: string + directory: string + chatKey: string + message: string + channel?: AuditEntry["channel"] + }) => Effect.Effect<{ reply: string; blocked: boolean }, AgentUINotFoundError> + // Appends one turn to an agent's audit log — called by every channel + // (WhatsApp/sandbox via dispatchChannelMessage, Telegram from its own + // separate dispatch path since it doesn't go through that function) so + // "what messages came in, what the agent said back" is inspectable + // after the fact, not just visible live in the channel itself. + readonly logAudit: (id: string, input: Omit) => Effect.Effect + // Newest first, capped — see AUDIT_LOG_CAP. + readonly listAudit: (id: string) => Effect.Effect // "Criar com IA": one-shot generation — the user describes the agent // they want in natural language, this drafts the form fields a real // conversation-builder would otherwise ask about turn by turn (name, @@ -137,6 +182,7 @@ const layer = Layer.effect( const promptSvc = yield* SessionPrompt.Service const instanceStore = yield* InstanceStore.Service const provider = yield* Provider.Service + const storage = yield* Storage.Service // Same overlay-on-top-of-disk-config pattern as Batuta.Service and // Combo.Service (packages/opencode/src/batuta/index.ts, src/combo/index.ts) @@ -269,19 +315,45 @@ const layer = Layer.effect( return { allowed: true } } - const sessionPermission = (): PermissionV1.Ruleset => [ - { permission: "bash", pattern: "*", action: "deny" }, - { permission: "task", pattern: "*", action: "deny" }, - { permission: "edit", pattern: "*", action: "deny" }, - { permission: "write", pattern: "*", action: "deny" }, - { permission: "external_directory", pattern: "*", action: "deny" }, + const sessionPermission = (mcpServers?: readonly string[]): PermissionV1.Ruleset => [ + // Wildcard deny-everything, not a per-category list: anything not + // covered by an explicit rule below falls through to the *default* + // permission action, which for tools outside this short list (e.g. + // todowrite, webfetch, lsp, skill — none of them bash/task/edit/ + // write/external_directory) is "ask". A channel dispatch has no + // human attached to answer that prompt, so the tool call — and the + // whole assistant turn — silently stalls: the loop still exits (its + // finish reason isn't "tool-calls"/"unknown") but with zero parts, + // producing the "(sem resposta)" fallback with no error anywhere. + // Root-caused 2026-09-11 against a live izapia webhook: the model + // call itself completed fine (confirmed working in a normal + // session with the same model), only channel-dispatched sessions + // hit this. See git history for the per-category list this replaced. + { permission: "*", pattern: "*", action: "deny" }, + ...(mcpServers ?? []).map( + (server): PermissionV1.Rule => ({ + permission: `${McpCatalog.sanitize(server)}_*`, + pattern: "*", + action: "allow", + }), + ), ] const resolveModel = Effect.fn("AgentUI.resolveModel")(function* (spec: string) { if (spec.startsWith("combo:")) { return yield* combos.resolve(spec.slice("combo:".length)).pipe(Effect.orElseSucceed(() => undefined)) } - const [providerID, modelID] = spec.split("/") + // Split on the FIRST "/" only — some providers (Omniroute) encode + // their own namespace into the model id itself (e.g. + // "omnrt/agy/gemini-3.7-flash-tiered"), so a full spec.split("/") + // truncated modelID to just "agy", losing everything after the + // second slash and producing a "Model not found: omnrt/agy" error. + // Same first-slash-only convention ModelPickerV2's splitModel() uses + // client-side. + const separator = spec.indexOf("/") + if (separator < 0) return undefined + const providerID = spec.slice(0, separator) + const modelID = spec.slice(separator + 1) if (!providerID || !modelID) return undefined return { providerID, modelID } }) @@ -294,31 +366,72 @@ const layer = Layer.effect( .trim() } - // One sandbox session per agent, independent of any real channel's - // sessions (Telegram keeps its own, keyed by chat+agent) — testing an - // agent never touches or gets touched by its real conversations. - const sandboxSessions = new Map() + // One session per (agent, chatKey) pair — the sandbox test chat uses a + // fixed "sandbox" chatKey (so it's independent of any real channel's + // sessions), while a real channel (WhatsApp today; Telegram's dedicated + // per-agent bots keep their own richer session map in Telegram.Service, + // with background-task queueing this generalized path intentionally + // doesn't have) passes its own chat/contact identifier so each sender + // gets their own conversation with the agent. + const channelSessions = new Map() - const testMessage = Effect.fn("AgentUI.testMessage")(function* (input: { + const AUDIT_LOG_CAP = 300 + const auditKey = (id: string) => ["agentui", "audit", id] + + const readAuditLog = (id: string) => + storage.read(auditKey(id)).pipe(Effect.orElseSucceed(() => [] as AuditEntry[])) + + const logAudit = Effect.fn("AgentUI.logAudit")(function* ( + id: string, + input: Omit, + ) { + const key = auditKey(id) + const existing = yield* readAuditLog(id) + const entry: AuditEntry = { id: crypto.randomUUID(), timestamp: Date.now(), ...input } + const next = [...existing, entry].slice(-AUDIT_LOG_CAP) + yield* storage.write(key, next).pipe( + Effect.tapError((cause) => Effect.logWarning("agentui audit write failed", { id, cause })), + Effect.ignore, + ) + }) + + const listAudit = Effect.fn("AgentUI.listAudit")(function* (id: string) { + const entries = yield* readAuditLog(id) + return [...entries].reverse() + }) + + const dispatchChannelMessage = Effect.fn("AgentUI.dispatchChannelMessage")(function* (input: { id: string directory: string + chatKey: string message: string + channel?: AuditEntry["channel"] }) { + const channel: AuditEntry["channel"] = input.channel ?? (input.chatKey === "sandbox" ? "sandbox" : "whatsapp") const agent = yield* get(input.id) if (!ConfigAgentUIV1.isEnabled(agent)) { return { reply: "Este agente está desativado. Ative-o para testar.", blocked: true } } const guard = checkInput(agent, input.message) - if (!guard.allowed) return { reply: `🛡️ ${guard.reason}`, blocked: true } + if (!guard.allowed) { + const reply = `🛡️ ${guard.reason}` + yield* logAudit(input.id, { channel, chatKey: input.chatKey, incoming: input.message, outgoing: reply, blocked: true }) + return { reply, blocked: true } + } const ctx = yield* instanceStore.load({ directory: input.directory }) + const sessionKey = `${input.id}:${input.chatKey}` const sessionID = yield* Effect.gen(function* () { - const existing = sandboxSessions.get(input.id) + const existing = channelSessions.get(sessionKey) if (existing) return existing const session = yield* sessions - .create({ title: `Sandbox: ${agent.name}`, directory: input.directory, permission: sessionPermission() }) + .create({ + title: `${agent.name}: ${input.chatKey}`, + directory: input.directory, + permission: sessionPermission(agent.mcpServers), + }) .pipe(Effect.provideService(InstanceRef, ctx)) - sandboxSessions.set(input.id, session.id) + channelSessions.set(sessionKey, session.id) return session.id }) @@ -341,16 +454,25 @@ const layer = Layer.effect( Effect.map((result) => extractText(result) || "(sem resposta)"), Effect.provideService(InstanceRef, ctx), Effect.catch((cause) => - Effect.logError("agentui sandbox prompt failed", { id: input.id, cause }).pipe( + Effect.logError("agentui channel prompt failed", { id: input.id, chatKey: input.chatKey, cause }).pipe( Effect.as(`⚠️ ${cause instanceof Error ? cause.message : String(cause)}`), ), ), ) + yield* logAudit(input.id, { channel, chatKey: input.chatKey, incoming: input.message, outgoing: reply, blocked: false }) return { reply, blocked: false } }) + const testMessage = Effect.fn("AgentUI.testMessage")(function* (input: { + id: string + directory: string + message: string + }) { + return yield* dispatchChannelMessage({ ...input, chatKey: "sandbox" }) + }) + const resetSandbox = Effect.fn("AgentUI.resetSandbox")(function* (id: string) { - sandboxSessions.delete(id) + channelSessions.delete(`${id}:sandbox`) }) const tryResolveDraftModel = (spec: string) => @@ -454,6 +576,9 @@ const layer = Layer.effect( testMessage, resetSandbox, generateDraft, + dispatchChannelMessage, + logAudit, + listAudit, }) }), ) @@ -461,5 +586,5 @@ const layer = Layer.effect( export const node = LayerNode.make({ service: Service, layer, - deps: [Config.node, Combo.node, Session.node, SessionPrompt.node, InstanceStore.node, Provider.node], + deps: [Config.node, Combo.node, Session.node, SessionPrompt.node, InstanceStore.node, Provider.node, Storage.node], }) diff --git a/packages/opencode/src/server/routes/instance/httpapi/api.ts b/packages/opencode/src/server/routes/instance/httpapi/api.ts index 53eec3770baa..59b9e6eaccb3 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/api.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/api.ts @@ -30,6 +30,8 @@ import { SessionApi } from "./groups/session" import { SyncApi } from "./groups/sync" import { TelegramApi } from "./groups/telegram" import { TuiApi } from "./groups/tui" +import { TunnelApi } from "./groups/tunnel" +import { WhatsAppApi } from "./groups/whatsapp" import { WorkspaceApi } from "./groups/workspace" import { makeApi } from "@opencode-ai/protocol/api" import { LocationMiddleware } from "@opencode-ai/server/location" @@ -85,6 +87,8 @@ export const InstanceHttpApi = HttpApi.make("opencode-instance") .addHttpApi(TelegramApi) .addHttpApi(MemoryApi) .addHttpApi(TuiApi) + .addHttpApi(WhatsAppApi) + .addHttpApi(TunnelApi) .addHttpApi(WorkspaceApi) .middleware(SchemaErrorMiddleware) diff --git a/packages/opencode/src/server/routes/instance/httpapi/groups/agentui.ts b/packages/opencode/src/server/routes/instance/httpapi/groups/agentui.ts index 3ce6f1b582b0..4b77a8c03441 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/groups/agentui.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/groups/agentui.ts @@ -1,7 +1,7 @@ import { ConfigAgentUIV1 } from "@opencode-ai/core/v1/config/agentui" import { Schema } from "effect" import { HttpApi, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi" -import { AgentUINotFoundError, AgentUIGenerateFailedError } from "@/agentui" +import { AgentUINotFoundError, AgentUIGenerateFailedError, AuditEntry } from "@/agentui" import { Authorization } from "../middleware/authorization" import { InstanceContextMiddleware } from "../middleware/instance-context" import { WorkspaceRoutingMiddleware, WorkspaceRoutingQuery } from "../middleware/workspace-routing" @@ -101,6 +101,18 @@ export const AgentUIApi = HttpApi.make("agentui") description: "Starts a fresh sandbox session for this agent on the next test message.", }), ), + HttpApiEndpoint.get("audit", `${root}/:id/audit`, { + params: { id: Schema.String }, + query: WorkspaceRoutingQuery, + success: described(Schema.Array(AuditEntry), "Audit log entries, newest first"), + }).annotateMerge( + OpenApi.annotations({ + identifier: "agentui.audit", + summary: "Get an AgentUI agent's audit log", + description: + "Lists recent turns (incoming message + the agent's reply) across every channel this agent is reachable on, newest first.", + }), + ), HttpApiEndpoint.delete("remove", `${root}/:id`, { params: { id: Schema.String }, query: WorkspaceRoutingQuery, diff --git a/packages/opencode/src/server/routes/instance/httpapi/groups/tunnel.ts b/packages/opencode/src/server/routes/instance/httpapi/groups/tunnel.ts new file mode 100644 index 000000000000..dedd1ac04946 --- /dev/null +++ b/packages/opencode/src/server/routes/instance/httpapi/groups/tunnel.ts @@ -0,0 +1,77 @@ +import { Schema } from "effect" +import { HttpApi, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi" +import { TunnelError, Status as TunnelStatus, TailscaleStatus } from "@/tunnel" +import { Authorization } from "../middleware/authorization" +import { InstanceContextMiddleware } from "../middleware/instance-context" +import { WorkspaceRoutingMiddleware } from "../middleware/workspace-routing" +import { described } from "./metadata" + +const root = "/tunnel" + +export const StartPayload = Schema.Struct({ port: Schema.Number }) + +export const TunnelApi = HttpApi.make("tunnel") + .add( + HttpApiGroup.make("tunnel") + .add( + // Starts (or returns the already-running) cloudflared quick tunnel + // exposing `http://localhost:` publicly — see Tunnel.Service. + // Used by the AgentUI form so a WhatsApp webhook URL pointing at + // 127.0.0.1/localhost can be swapped for one izapia (or any other + // waconector provider) can actually reach. + HttpApiEndpoint.post("start", `${root}/start`, { + payload: StartPayload, + success: described(TunnelStatus, "Tunnel started (or already running)"), + error: TunnelError, + }).annotateMerge( + OpenApi.annotations({ + identifier: "tunnel.start", + summary: "Start public tunnel", + description: "Starts a cloudflared quick tunnel exposing this server's given local port publicly.", + }), + ), + HttpApiEndpoint.get("status", `${root}/status`, { + success: described(TunnelStatus, "Current tunnel status"), + }).annotateMerge( + OpenApi.annotations({ + identifier: "tunnel.status", + summary: "Get tunnel status", + }), + ), + HttpApiEndpoint.post("stop", `${root}/stop`, { + success: described(Schema.Struct({ ok: Schema.Literal(true) }), "Tunnel stopped"), + }).annotateMerge( + OpenApi.annotations({ + identifier: "tunnel.stop", + summary: "Stop public tunnel", + }), + ), + // Detects a local Tailscale IP as a simpler alternative to the + // cloudflared quick tunnel above — no process to start/stop, just + // whatever `tailscale ip -4` reports for this machine right now. + HttpApiEndpoint.get("tailscale", `${root}/tailscale`, { + success: described(TailscaleStatus, "Local Tailscale IP, if available"), + }).annotateMerge( + OpenApi.annotations({ + identifier: "tunnel.tailscale", + summary: "Detect local Tailscale IP", + }), + ), + ) + .annotateMerge( + OpenApi.annotations({ + title: "tunnel", + description: "Experimental HttpApi public tunnel routes (cloudflared quick tunnel).", + }), + ) + .middleware(InstanceContextMiddleware) + .middleware(WorkspaceRoutingMiddleware) + .middleware(Authorization), + ) + .annotateMerge( + OpenApi.annotations({ + title: "opencode experimental HttpApi", + version: "0.0.1", + description: "Experimental HttpApi surface for selected instance routes.", + }), + ) diff --git a/packages/opencode/src/server/routes/instance/httpapi/groups/whatsapp.ts b/packages/opencode/src/server/routes/instance/httpapi/groups/whatsapp.ts new file mode 100644 index 000000000000..e51f260902d8 --- /dev/null +++ b/packages/opencode/src/server/routes/instance/httpapi/groups/whatsapp.ts @@ -0,0 +1,97 @@ +import { Schema } from "effect" +import { HttpApi, HttpApiEndpoint, HttpApiGroup, OpenApi } from "effect/unstable/httpapi" +import { AgentUINotFoundError } from "@/agentui" +import { + IzapiaGroup, + IzapiaSession, + WhatsAppChannelNotConfiguredError, + WhatsAppInvalidWebhookError, + WhatsAppProviderApiError, +} from "@/whatsapp" +import { InstanceContextMiddleware } from "../middleware/instance-context" +import { WorkspaceRoutingMiddleware, WorkspaceRoutingQuery } from "../middleware/workspace-routing" +import { described } from "./metadata" + +const root = "/whatsapp" + +export const WebhookResponse = Schema.Struct({ ok: Schema.Literal(true) }) +export const IzapiaSessionsPayload = Schema.Struct({ apiKey: Schema.String }) +export const IzapiaGroupsPayload = Schema.Struct({ apiKey: Schema.String, sids: Schema.Array(Schema.String) }) + +export const WhatsAppApi = HttpApi.make("whatsapp") + .add( + HttpApiGroup.make("whatsapp") + .add( + // Called by the WhatsApp gateway (WAHA/Evolution/Z-API/...), never by + // our own client — deliberately NOT gated by the Authorization + // middleware every other instance route uses, since an external + // provider can't present our session credentials. Protected instead + // by the per-channel `secret` path segment (see + // ConfigAgentUIV1.WhatsAppChannelBinding.webhookSecret): unguessable, + // generated once per channel, embedded in the URL handed to the + // provider. `directory` (which instance/project this agent belongs + // to) travels the same way, as a query param on that same URL — + // WorkspaceRoutingMiddleware still needs it to route the request, + // same as every other instance-scoped endpoint. + HttpApiEndpoint.post("webhook", `${root}/webhook/:agentId/:secret`, { + params: { agentId: Schema.String, secret: Schema.String }, + query: WorkspaceRoutingQuery, + payload: Schema.Unknown, + success: described(WebhookResponse, "Webhook processed"), + error: [AgentUINotFoundError, WhatsAppChannelNotConfiguredError, WhatsAppInvalidWebhookError], + }).annotateMerge( + OpenApi.annotations({ + identifier: "whatsapp.webhook", + summary: "Receive a WhatsApp webhook for an AgentUI agent", + description: + "Inbound webhook endpoint for the agent's configured WhatsApp channel (via waconector). Never call this directly — it's the URL configured on the WhatsApp gateway itself.", + }), + ), + // Called by our own client (the agent form's "buscar sessões" + // button) — deliberately not gated by the Authorization middleware + // either, but for a different reason than the webhook route above: + // it carries no server-side secret at all, just proxies the caller- + // supplied `apiKey` straight to izapia's own API. Worst case, a + // caller who already holds some izapia API key uses this endpoint + // to list that key's own sessions — nothing an authenticated opencode + // session wouldn't already let them do directly against izapia. + HttpApiEndpoint.post("izapiaSessions", `${root}/izapia/sessions`, { + payload: IzapiaSessionsPayload, + success: described(Schema.Array(IzapiaSession), "Sessions for this izapia tenant"), + error: WhatsAppProviderApiError, + }).annotateMerge( + OpenApi.annotations({ + identifier: "whatsapp.izapiaSessions", + summary: "List izapia sessions", + description: "Lists the WhatsApp sessions already created for the tenant that owns the given izapia API key.", + }), + ), + // Same reasoning as izapiaSessions above — no server-side secret, + // just proxies the caller-supplied credentials. + HttpApiEndpoint.post("izapiaGroups", `${root}/izapia/groups`, { + payload: IzapiaGroupsPayload, + success: described(Schema.Array(IzapiaGroup), "Groups across the given izapia sessions"), + }).annotateMerge( + OpenApi.annotations({ + identifier: "whatsapp.izapiaGroups", + summary: "List izapia groups", + description: "Lists WhatsApp groups across the given izapia sessions, deduped by group id.", + }), + ), + ) + .annotateMerge( + OpenApi.annotations({ + title: "whatsapp", + description: "Experimental HttpApi WhatsApp channel webhook route.", + }), + ) + .middleware(InstanceContextMiddleware) + .middleware(WorkspaceRoutingMiddleware), + ) + .annotateMerge( + OpenApi.annotations({ + title: "opencode experimental HttpApi", + version: "0.0.1", + description: "Experimental HttpApi surface for selected instance routes.", + }), + ) diff --git a/packages/opencode/src/server/routes/instance/httpapi/handlers/agentui.ts b/packages/opencode/src/server/routes/instance/httpapi/handlers/agentui.ts index ade44448de9c..9fe021af5424 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/handlers/agentui.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/handlers/agentui.ts @@ -45,6 +45,10 @@ export const agentuiHandlers = HttpApiBuilder.group(InstanceHttpApi, "agentui", return yield* agentui.generateDraft({ description: ctx.payload.description }) }) + const audit = Effect.fn("AgentUIHttpApi.audit")(function* (ctx: { params: { id: string } }) { + return yield* agentui.listAudit(ctx.params.id) + }) + return handlers .handle("list", list) .handle("get", get) @@ -53,5 +57,6 @@ export const agentuiHandlers = HttpApiBuilder.group(InstanceHttpApi, "agentui", .handle("test", test) .handle("resetSandbox", resetSandbox) .handle("generate", generate) + .handle("audit", audit) }), ) diff --git a/packages/opencode/src/server/routes/instance/httpapi/handlers/tunnel.ts b/packages/opencode/src/server/routes/instance/httpapi/handlers/tunnel.ts new file mode 100644 index 000000000000..5f4093cb06be --- /dev/null +++ b/packages/opencode/src/server/routes/instance/httpapi/handlers/tunnel.ts @@ -0,0 +1,29 @@ +import { Tunnel } from "@/tunnel" +import { Effect } from "effect" +import { HttpApiBuilder } from "effect/unstable/httpapi" +import { InstanceHttpApi } from "../api" + +export const tunnelHandlers = HttpApiBuilder.group(InstanceHttpApi, "tunnel", (handlers) => + Effect.gen(function* () { + const tunnel = yield* Tunnel.Service + + const start = Effect.fn("TunnelHttpApi.start")(function* (ctx: { payload: { port: number } }) { + return yield* tunnel.start({ port: ctx.payload.port }) + }) + + const status = Effect.fn("TunnelHttpApi.status")(function* () { + return yield* tunnel.status() + }) + + const stop = Effect.fn("TunnelHttpApi.stop")(function* () { + yield* tunnel.stop() + return { ok: true as const } + }) + + const tailscale = Effect.fn("TunnelHttpApi.tailscale")(function* () { + return yield* tunnel.tailscale() + }) + + return handlers.handle("start", start).handle("status", status).handle("stop", stop).handle("tailscale", tailscale) + }), +) diff --git a/packages/opencode/src/server/routes/instance/httpapi/handlers/whatsapp.ts b/packages/opencode/src/server/routes/instance/httpapi/handlers/whatsapp.ts new file mode 100644 index 000000000000..c09063566637 --- /dev/null +++ b/packages/opencode/src/server/routes/instance/httpapi/handlers/whatsapp.ts @@ -0,0 +1,47 @@ +import { WhatsApp } from "@/whatsapp" +import { Effect } from "effect" +import { HttpServerRequest, HttpServerResponse } from "effect/unstable/http" +import { HttpApiBuilder } from "effect/unstable/httpapi" +import { InstanceHttpApi } from "../api" + +export const whatsappHandlers = HttpApiBuilder.group(InstanceHttpApi, "whatsapp", (handlers) => + Effect.gen(function* () { + const whatsapp = yield* WhatsApp.Service + + // handleRaw, not handle — the payload shape is whatever JSON the + // selected provider's webhook posts (no fixed schema across 9 + // providers), and we want direct access to the raw request headers to + // hand straight to waconector's parser. + const webhook = Effect.fn("WhatsAppHttpApi.webhook")(function* (ctx: { + params: { agentId: string; secret: string } + request: HttpServerRequest.HttpServerRequest + }) { + const body = yield* Effect.orDie(ctx.request.json) + const headers: Record = { ...ctx.request.headers } + const result = yield* whatsapp.handleWebhook({ + agentID: ctx.params.agentId, + secret: ctx.params.secret, + body, + headers, + }) + return HttpServerResponse.jsonUnsafe(result) + }) + + const izapiaSessions = Effect.fn("WhatsAppHttpApi.izapiaSessions")(function* (ctx: { + payload: { apiKey: string } + }) { + return yield* whatsapp.listIzapiaSessions({ apiKey: ctx.payload.apiKey }) + }) + + const izapiaGroups = Effect.fn("WhatsAppHttpApi.izapiaGroups")(function* (ctx: { + payload: { apiKey: string; sids: readonly string[] } + }) { + return yield* whatsapp.listIzapiaGroups({ apiKey: ctx.payload.apiKey, sids: [...ctx.payload.sids] }) + }) + + return handlers + .handleRaw("webhook", webhook) + .handle("izapiaSessions", izapiaSessions) + .handle("izapiaGroups", izapiaGroups) + }), +) diff --git a/packages/opencode/src/server/routes/instance/httpapi/server.ts b/packages/opencode/src/server/routes/instance/httpapi/server.ts index 6169db133fd0..d47cf5a2903d 100644 --- a/packages/opencode/src/server/routes/instance/httpapi/server.ts +++ b/packages/opencode/src/server/routes/instance/httpapi/server.ts @@ -23,6 +23,8 @@ import { Memory } from "@/memory" import { Batuta } from "@/batuta" import { Combo } from "@/combo" import { AgentUI } from "@/agentui" +import { WhatsApp } from "@/whatsapp" +import { Tunnel } from "@/tunnel" import { McpAuth } from "@/mcp/auth" import { Permission } from "@/permission" import { Plugin } from "@/plugin" @@ -110,6 +112,8 @@ import { syncHandlers } from "./handlers/sync" import { telegramHandlers } from "./handlers/telegram" import { memoryHandlers } from "./handlers/memory" import { tuiHandlers } from "./handlers/tui" +import { whatsappHandlers } from "./handlers/whatsapp" +import { tunnelHandlers } from "./handlers/tunnel" import { handlers } from "@opencode-ai/server/handlers" import { buildLocationServiceMap, LocationServiceMap } from "@opencode-ai/core/location-services" import { layer as locationLayer } from "@opencode-ai/server/location" @@ -184,6 +188,8 @@ const instanceApiRoutes = HttpApiBuilder.layer(InstanceHttpApi).pipe( telegramHandlers, memoryHandlers, tuiHandlers, + whatsappHandlers, + tunnelHandlers, workspaceHandlers, ]), ) @@ -271,6 +277,8 @@ const app = LayerNode.group([ Batuta.node, Combo.node, AgentUI.node, + WhatsApp.node, + Tunnel.node, Command.node, Truncate.node, ToolRegistry.node, diff --git a/packages/opencode/src/telegram/index.ts b/packages/opencode/src/telegram/index.ts index a3881406c32a..241d84baa722 100644 --- a/packages/opencode/src/telegram/index.ts +++ b/packages/opencode/src/telegram/index.ts @@ -491,8 +491,13 @@ const layer = Layer.effect( if (agentKey) { const existing = agentSessionsByChat.get(agentKey) if (existing) return SessionID.make(existing) + const agent = yield* agentUI.get(agentKey).pipe(Effect.orElseSucceed(() => undefined)) const session = yield* sessions - .create({ title: `Telegram AgentUI: ${agentKey}`, directory, permission: agentUI.sessionPermission() }) + .create({ + title: `Telegram AgentUI: ${agentKey}`, + directory, + permission: agentUI.sessionPermission(agent?.mcpServers), + }) .pipe(Effect.provideService(InstanceRef, ctx)) agentSessionsByChat.set(agentKey, session.id) return session.id @@ -839,12 +844,33 @@ const layer = Layer.effect( const guard = agentUI.checkInput(agent, rest) if (!guard.allowed) { reply = `🛡️ ${guard.reason}` + yield* agentUI.logAudit(agent.id, { + channel: "telegram", + chatKey: String(chatId), + incoming: rest, + outgoing: reply, + blocked: true, + }) } else { const model = yield* agentUI.resolveModel(agent.model) const knowledge = yield* agentUI.buildKnowledgeContext(agent) const personality = knowledge ? `${agent.personality}\n\n${knowledge}` : agent.personality const system = agentUI.hardenSystemPrompt(agent, personality) reply = yield* dispatchTask(token, chatId, directory, rest, attachments, { system, model }, `${chatId}:${agent.id}`) + // dispatchTask can return undefined when the reply is queued as a + // background task instead of answered inline (e.g. a parallel + // run) — that final answer isn't captured here; a real fix would + // hook the background-task completion path too, out of scope for + // this first pass at an audit log. + if (reply) { + yield* agentUI.logAudit(agent.id, { + channel: "telegram", + chatKey: String(chatId), + incoming: rest, + outgoing: reply, + blocked: false, + }) + } } } else if (text.startsWith("/")) { const [command, ...rest] = text.slice(1).split(/\s+/) diff --git a/packages/opencode/src/tunnel/index.ts b/packages/opencode/src/tunnel/index.ts new file mode 100644 index 000000000000..14a7cdfa8fbf --- /dev/null +++ b/packages/opencode/src/tunnel/index.ts @@ -0,0 +1,214 @@ +export * as Tunnel from "./index" + +import { LayerNode } from "@opencode-ai/core/effect/layer-node" +import { Context, Effect, Layer, Schema } from "effect" +import * as NodeChildProcess from "node:child_process" +import type { Readable } from "node:stream" + +// Quick, no-account cloudflared tunnel — exposes this server's HTTP port at +// a random https://*.trycloudflare.com URL, which is what a remote webhook +// sender (izapia, or any other waconector provider) needs to reach a +// server otherwise only listening on 127.0.0.1/localhost. See +// AgentUIFormPage's whatsappWebhookUrl for the consumer of this. + +export class TunnelError extends Schema.TaggedErrorClass()("TunnelError", { + reason: Schema.String, +}) { + override get message() { + return `Falha ao iniciar o túnel público: ${this.reason}` + } +} + +export const Status = Schema.Struct({ + running: Schema.Boolean, + url: Schema.optional(Schema.String), +}) +export type Status = Schema.Schema.Type + +export const TailscaleStatus = Schema.Struct({ + available: Schema.Boolean, + ip: Schema.optional(Schema.String), +}) +export type TailscaleStatus = Schema.Schema.Type + +export interface Interface { + readonly start: (input: { port: number }) => Effect.Effect + readonly status: () => Effect.Effect + readonly stop: () => Effect.Effect + readonly tailscale: () => Effect.Effect +} + +export class Service extends Context.Service()("@opencode/Tunnel") {} + +// cloudflared prints the assigned URL to stderr, on a line that looks like +// "... | https://random-two-words.trycloudflare.com |". stdout carries +// mostly unrelated connection-status logging — checked either way in case +// that changes between versions. +const URL_PATTERN = /https:\/\/[a-z0-9-]+\.trycloudflare\.com/i +const START_TIMEOUT_MS = 20_000 + +const layer = Layer.effect( + Service, + Effect.gen(function* () { + // One tunnel for the whole server process. Every WhatsApp channel on + // every agent hits the same HTTP listener regardless of which + // project/directory it's scoped to, so there's never a reason to run + // more than one at once — starting a second one just reuses whatever + // is already running (or already starting) instead of spawning again. + // Not persisted across process restarts: a fresh app launch means a + // fresh tunnel, and any webhook URL pasted into a provider's dashboard + // from a previous run goes stale. Acceptable for this phase — flagged + // here rather than solved, same as the "no directory yet" gaps + // elsewhere in this feature. + let child: NodeChildProcess.ChildProcessByStdio | undefined + let url: string | undefined + let starting: Promise | undefined + + const reset = () => { + child = undefined + url = undefined + starting = undefined + } + + const spawnAndWait = (port: number): Promise => + new Promise((resolve, reject) => { + let proc: NodeChildProcess.ChildProcessByStdio + try { + proc = NodeChildProcess.spawn("cloudflared", ["tunnel", "--url", `http://localhost:${port}`], { + stdio: ["ignore", "pipe", "pipe"], + }) + } catch (cause) { + reset() + reject(new TunnelError({ reason: String(cause) })) + return + } + child = proc + + let settled = false + const onOutput = (chunk: Buffer) => { + if (settled) return + const match = chunk.toString().match(URL_PATTERN) + if (!match) return + settled = true + url = match[0] + resolve({ running: true, url }) + } + proc.stdout.on("data", onOutput) + proc.stderr.on("data", onOutput) + proc.on("error", (cause) => { + if (settled) return + settled = true + reset() + reject(new TunnelError({ reason: String(cause) })) + }) + proc.on("exit", (code) => { + if (settled) { + // Process died after we already resolved a URL — clear state + // so the next start() attempt spawns fresh instead of + // reporting a tunnel that's actually gone. + reset() + return + } + settled = true + reset() + reject(new TunnelError({ reason: `cloudflared não iniciou instalado ou saiu com código ${code}` })) + }) + const timer = setTimeout(() => { + if (settled) return + settled = true + proc.kill() + reset() + reject(new TunnelError({ reason: "tempo esgotado esperando o cloudflared imprimir a URL pública" })) + }, START_TIMEOUT_MS) + proc.once("exit", () => clearTimeout(timer)) + }) + + const start = Effect.fn("Tunnel.start")(function* (input: { port: number }) { + if (url) return { running: true, url } + if (!starting) starting = spawnAndWait(input.port) + return yield* Effect.tryPromise({ + try: () => starting!, + catch: (cause) => (cause instanceof TunnelError ? cause : new TunnelError({ reason: String(cause) })), + }) + }) + + const status = Effect.fn("Tunnel.status")(function* () { + return { running: !!child, url } + }) + + const stop = Effect.fn("Tunnel.stop")(function* () { + child?.kill() + reset() + }) + + // Simpler alternative to the cloudflared quick tunnel: if the user + // already has Tailscale running on both this machine and the remote + // provider (see izapia's own VPS in this project's Tailscale-based + // setups), the provider can reach this server directly over the + // tailnet at its 100.x.x.x address — no tunnel process needed at all. + // `tailscale ip -4` already scopes its output to the tailnet address, + // so no CGNAT-range parsing is needed here. + // + // The GUI installs of Tailscale (Windows, macOS App Store build) don't + // put `tailscale` on PATH, only the CLI-first installs (winget's CLI + // package, Linux, Homebrew) do — so a plain spawn("tailscale", ...) + // silently ENOENTs on a very common, fully-working setup. Fall back to + // each platform's known GUI-bundled CLI location before giving up. + const TAILSCALE_CANDIDATES = + process.platform === "win32" + ? ["tailscale", "C:\\Program Files\\Tailscale\\tailscale.exe"] + : process.platform === "darwin" + ? ["tailscale", "/Applications/Tailscale.app/Contents/MacOS/Tailscale", "/usr/local/bin/tailscale"] + : ["tailscale"] + + const tryTailscaleIp = (command: string): Promise => + new Promise((resolve) => { + let proc: NodeChildProcess.ChildProcess + try { + proc = NodeChildProcess.spawn(command, ["ip", "-4"], { stdio: ["ignore", "pipe", "ignore"] }) + } catch { + resolve({ available: false }) + return + } + let out = "" + let settled = false + proc.stdout?.on("data", (chunk: Buffer) => { + out += chunk.toString() + }) + proc.on("error", () => { + if (settled) return + settled = true + resolve({ available: false }) + }) + proc.on("exit", (code) => { + if (settled) return + settled = true + const ip = out.trim().split("\n")[0]?.trim() + resolve(code === 0 && ip ? { available: true, ip } : { available: false }) + }) + const timer = setTimeout(() => { + if (settled) return + settled = true + proc.kill() + resolve({ available: false }) + }, 3_000) + proc.once("exit", () => clearTimeout(timer)) + }) + + const detectTailscaleIp = async (): Promise => { + for (const command of TAILSCALE_CANDIDATES) { + const result = await tryTailscaleIp(command) + if (result.available) return result + } + return { available: false } + } + + const tailscale = Effect.fn("Tunnel.tailscale")(function* () { + return yield* Effect.promise(detectTailscaleIp) + }) + + return Service.of({ start, status, stop, tailscale }) + }), +) + +export const node = LayerNode.make({ service: Service, layer, deps: [] }) diff --git a/packages/opencode/src/whatsapp/index.ts b/packages/opencode/src/whatsapp/index.ts new file mode 100644 index 000000000000..d67393529b07 --- /dev/null +++ b/packages/opencode/src/whatsapp/index.ts @@ -0,0 +1,425 @@ +export * as WhatsApp from "./index" + +import { LayerNode } from "@opencode-ai/core/effect/layer-node" +import { ConfigAgentUIV1 } from "@opencode-ai/core/v1/config/agentui" +import { AgentUI, AgentUINotFoundError } from "@/agentui" +import { Context, Duration, Effect, Fiber, Layer, Schedule, Schema } from "effect" +import * as Scope from "effect/Scope" +import { createConnector, type WaAdapter } from "waconector" +import { waha } from "waconector/waha" +import { evolution } from "waconector/evolution" +import { zapi } from "waconector/zapi" +import { uazapi } from "waconector/uazapi" +import { whapi } from "waconector/whapi" +import { wuzapi } from "waconector/wuzapi" +import { quepasa } from "waconector/quepasa" +import { wppconnect } from "waconector/wppconnect" +import { izapia } from "waconector/izapia" + +// Phase 2 of "Canais" (Channels) for AgentUI (#144 follow-up) — WhatsApp via +// waconector (https://alltomatos.github.io/waconector/), which wraps 9 +// unofficial WhatsApp APIs (5 self-hosted, 4 SaaS/private) behind one +// contract. Unlike Telegram (long-poll — see Telegram.Service), waconector +// is webhook-only: every provider calls US, so this service is a webhook +// receiver, not a poll loop. See groups/handlers/whatsapp.ts for the +// (deliberately unauthenticated, secret-in-URL-protected) HTTP route. + +export class WhatsAppChannelNotConfiguredError extends Schema.TaggedErrorClass()( + "WhatsAppChannelNotConfiguredError", + { id: Schema.String }, +) { + override get message() { + return `Este agente não tem canal WhatsApp configurado: ${this.id}` + } +} + +export class WhatsAppInvalidWebhookError extends Schema.TaggedErrorClass()( + "WhatsAppInvalidWebhookError", + { reason: Schema.String }, +) { + override get message() { + return `Webhook do WhatsApp inválido: ${this.reason}` + } +} + +export class WhatsAppProviderApiError extends Schema.TaggedErrorClass()( + "WhatsAppProviderApiError", + { reason: Schema.String }, +) { + override get message() { + return `Falha ao consultar a API do provedor de WhatsApp: ${this.reason}` + } +} + +export const IzapiaSession = Schema.Struct({ + id: Schema.String, + name: Schema.optional(Schema.String), + status: Schema.String, + jid: Schema.optional(Schema.String), +}) +export type IzapiaSession = Schema.Schema.Type + +export const IzapiaGroup = Schema.Struct({ + id: Schema.String, + subject: Schema.String, + sessionId: Schema.String, + participantCount: Schema.Number, +}) +export type IzapiaGroup = Schema.Schema.Type + +export interface ProviderField { + readonly key: string + readonly required: boolean + readonly label: string +} + +// Sourced directly from each adapter's shipped .d.ts (packages/opencode +// depends on the real `waconector` package — these are NOT guesses from the +// docs site, which uses different factory names/fields than the actual +// package). Only the fields needed to actually connect are listed here — +// advanced per-adapter tuning (timeoutMs, retries, subscribe[], ...) is out +// of scope for this phase's UI. +export const PROVIDER_FIELDS: Record = { + waha: [ + { key: "baseUrl", required: true, label: "URL base (ex.: http://localhost:3000)" }, + { key: "apiKey", required: true, label: "API Key (X-Api-Key)" }, + { key: "session", required: false, label: "Nome da sessão (padrão: default)" }, + ], + evolution: [ + { key: "baseUrl", required: true, label: "URL base do servidor Evolution GO" }, + { key: "apiKey", required: true, label: "API Key da instância" }, + ], + zapi: [ + { key: "instanceId", required: true, label: "Instance ID" }, + { key: "token", required: true, label: "Token da instância" }, + { key: "clientToken", required: false, label: "Client-Token (se ativado na conta)" }, + ], + uazapi: [ + { key: "baseUrl", required: true, label: "URL base (ex.: https://minhaempresa.uazapi.com)" }, + { key: "token", required: true, label: "Token da instância" }, + ], + whapi: [{ key: "token", required: true, label: "Token do canal (Bearer)" }], + wuzapi: [ + { key: "baseUrl", required: true, label: "URL base do servidor Wuzapi" }, + { key: "token", required: true, label: "Token do usuário" }, + ], + quepasa: [ + { key: "baseUrl", required: true, label: "URL base da instância QuePasa" }, + { key: "token", required: true, label: "Token da instância" }, + ], + wppconnect: [ + { key: "baseUrl", required: true, label: "URL base do servidor WPPConnect" }, + { key: "session", required: true, label: "Nome da sessão" }, + { key: "token", required: true, label: "Token Bearer da sessão" }, + ], + // No "sid" field here on purpose — izapia is multi-session, so which + // session(s) this channel listens on is `WhatsAppChannelBinding.sessionIds` + // (picked from the "buscar sessões" list in the form), not a config field. + izapia: [{ key: "apiKey", required: true, label: "API key do tenant" }], +} + +// izapia é SaaS multi-tenant de URL fixa (https://api.izapia.com) — ao +// contrário dos outros providers self-hosted/SaaS acima, não há servidor do +// usuário para apontar, então esse campo nem aparece no form. +const IZAPIA_BASE_URL = "https://api.izapia.com" + +// `sidOverride` exists for izapia's multi-session channels: a channel may +// listen on several sessions at once (`channel.sessionIds`), but the +// WaAdapter contract binds to exactly one at construction time — the +// caller picks which one per call (parsing a webhook doesn't care, sending +// a reply must go out through the same session the message arrived on). +function buildAdapter(channel: ConfigAgentUIV1.WhatsAppChannelBinding, sidOverride?: string): WaAdapter { + const cfg = channel.config + switch (channel.provider) { + case "waha": + return waha({ baseUrl: cfg.baseUrl ?? "", apiKey: cfg.apiKey ?? "", session: cfg.session }) + case "evolution": + return evolution({ baseUrl: cfg.baseUrl ?? "", apiKey: cfg.apiKey ?? "" }) + case "zapi": + return zapi({ instanceId: cfg.instanceId ?? "", token: cfg.token ?? "", clientToken: cfg.clientToken }) + case "uazapi": + return uazapi({ baseUrl: cfg.baseUrl ?? "", token: cfg.token ?? "" }) + case "whapi": + return whapi({ token: cfg.token ?? "" }) + case "wuzapi": + return wuzapi({ baseUrl: cfg.baseUrl ?? "", token: cfg.token ?? "" }) + case "quepasa": + return quepasa({ baseUrl: cfg.baseUrl ?? "", token: cfg.token ?? "" }) + case "wppconnect": + return wppconnect({ baseUrl: cfg.baseUrl ?? "", session: cfg.session ?? "", token: cfg.token ?? "" }) + case "izapia": + return izapia({ baseUrl: IZAPIA_BASE_URL, apiKey: cfg.apiKey ?? "", sid: sidOverride ?? channel.sessionIds?.[0] ?? cfg.sid ?? "" }) + } +} + +// A group JID (`...@g.us`) is only answered if explicitly allow-listed; +// a direct-message JID (`...@s.whatsapp.net`) or anything else is always +// answered. See ConfigAgentUIV1.WhatsAppChannelBinding.allowedGroups. +function isChatAllowed(channel: ConfigAgentUIV1.WhatsAppChannelBinding, chatId: string): boolean { + if (!chatId.endsWith("@g.us")) return true + return (channel.allowedGroups ?? []).includes(chatId) +} + +function findChannel(agent: ConfigAgentUIV1.Agent): ConfigAgentUIV1.WhatsAppChannelBinding | undefined { + return agent.channels.find((c): c is ConfigAgentUIV1.WhatsAppChannelBinding => c.type === "whatsapp") +} + +export interface Interface { + readonly handleWebhook: (input: { + agentID: string + secret: string + body: unknown + headers: Record + }) => Effect.Effect<{ ok: true }, AgentUINotFoundError | WhatsAppChannelNotConfiguredError | WhatsAppInvalidWebhookError> + // Lets the form fetch the tenant's existing WhatsApp sessions (izapia + // calls them that, not "instances") right after the person pastes their + // API key, instead of making them go find and copy a sid by hand from + // the izapia dashboard. + readonly listIzapiaSessions: (input: { apiKey: string }) => Effect.Effect + // Lets the form fetch the groups each selected session belongs to, so the + // person can pick exactly which ones this agent should respond in — see + // ConfigAgentUIV1.WhatsAppChannelBinding.allowedGroups. + readonly listIzapiaGroups: (input: { apiKey: string; sids: string[] }) => Effect.Effect +} + +export class Service extends Context.Service()("@opencode/WhatsApp") {} + +// How long to wait after a message arrives before actually dispatching it — +// gives a person who fires off several WhatsApp bubbles in a row (very +// common; WhatsApp itself encourages short messages) a window to finish +// before the agent replies to just the first fragment. Each new message for +// the same (agent, chat) pair during the window cancels and restarts the +// wait and gets appended to the same batch, joined by newlines into one +// prompt. Tune by feel — too short defeats the point, too long feels +// unresponsive for genuinely single-shot messages. +const DEBOUNCE = Duration.seconds(4) + +interface PendingBatch { + texts: string[] + fiber: Fiber.Fiber +} + +const layer = Layer.effect( + Service, + Effect.gen(function* () { + const agentUI = yield* AgentUI.Service + const scope = yield* Scope.Scope + const pending = new Map() + + // Best-effort — a stalled/erroring provider presence call should never + // block or fail the actual reply. Not every provider implements + // presence.setTyping (optional in the WaAdapter contract), hence the + // Effect.sync wrapper: nothing to await when it's absent. + const setTyping = (channel: ConfigAgentUIV1.WhatsAppChannelBinding, sid: string | undefined, to: string) => + Effect.gen(function* () { + const connector = createConnector(buildAdapter(channel, sid)) + const setter = connector.presence?.setTyping + if (!setter) return + yield* Effect.tryPromise(() => setter({ to, state: "composing" })) + }).pipe(Effect.ignore) + + const flushBatch = (input: { + agentID: string + directory: string + channel: ConfigAgentUIV1.WhatsAppChannelBinding + chatId: string + instanceId: string | undefined + key: string + }) => + Effect.gen(function* () { + const batch = pending.get(input.key) + pending.delete(input.key) + if (!batch) return + yield* setTyping(input.channel, input.instanceId, input.chatId) + const result = yield* agentUI.dispatchChannelMessage({ + id: input.agentID, + directory: input.directory, + chatKey: input.chatId, + message: batch.texts.join("\n"), + }) + if (!result.reply) return + const replyAdapter = buildAdapter(input.channel, input.instanceId) + // The adapter's own HttpClient already retries a 429/5xx twice with a + // short (sub-second to few-second) backoff — fine for a background + // groups/sessions lookup, not enough once the whole tenant's rate + // budget is already exhausted (observed 2026-09-11: a burst of + // groups.list calls from repeatedly reopening the agent form starved + // the account's quota, and the actual reply send failed outright + // with no further attempt, silently dropping the answer the model + // had already produced). Actually delivering the reply matters far + // more than any background lookup, so it gets its own slower, + // longer-patience retry on top: a few attempts spread over ~30s. + yield* Effect.tryPromise(() => + createConnector(replyAdapter).messages.sendText({ to: input.chatId, text: result.reply }), + ).pipe( + Effect.retry({ schedule: Schedule.exponential("2 seconds").pipe(Schedule.both(Schedule.recurs(4))) }), + Effect.tapError((cause) => Effect.logError("whatsapp sendText failed", { agentID: input.agentID, cause })), + Effect.ignore, + ) + }) + + // Appends to the in-flight batch for this (agent, chat) pair if there is + // one, cancelling its pending flush and restarting the debounce window; + // otherwise starts a new batch. The flush runs as a daemon fiber so + // handleWebhook can return its 200 immediately without holding the + // provider's webhook request open for the whole debounce window. + const enqueue = (input: { + agentID: string + directory: string + channel: ConfigAgentUIV1.WhatsAppChannelBinding + chatId: string + instanceId: string | undefined + text: string + }) => + Effect.gen(function* () { + const key = `${input.agentID}:${input.chatId}` + const existing = pending.get(key) + if (existing) yield* Fiber.interrupt(existing.fiber) + const texts = [...(existing?.texts ?? []), input.text] + const fiber = yield* Effect.sleep(DEBOUNCE) + .pipe( + Effect.andThen(() => + flushBatch({ + agentID: input.agentID, + directory: input.directory, + channel: input.channel, + chatId: input.chatId, + instanceId: input.instanceId, + key, + }), + ), + ) + .pipe(Effect.ignore, Effect.forkIn(scope)) + pending.set(key, { texts, fiber }) + }) + + const handleWebhook = Effect.fn("WhatsApp.handleWebhook")(function* (input: { + agentID: string + secret: string + body: unknown + headers: Record + }) { + const agent = yield* agentUI.get(input.agentID) + const channel = findChannel(agent) + if (!channel) return yield* new WhatsAppChannelNotConfiguredError({ id: input.agentID }) + if (channel.webhookSecret !== input.secret) { + return yield* new WhatsAppInvalidWebhookError({ reason: "secret mismatch" }) + } + // Silently drop (not an error — the provider must still get a 200 or + // it will keep retrying/backing off) rather than dispatch to a + // disabled agent or one missing the directory it needs to run a + // session against. + if (!ConfigAgentUIV1.isEnabled(agent) || !channel.directory) return { ok: true as const } + const directory = channel.directory + + // Parsing itself doesn't depend on which session is bound (see + // izapia's parseWebhook — no sid in scope), so any configured session + // works to build the throwaway parsing adapter. + const parseAdapter = buildAdapter(channel) + const events = yield* Effect.try({ + try: () => createConnector(parseAdapter).webhooks.parse({ body: input.body, headers: input.headers }), + catch: (cause) => new WhatsAppInvalidWebhookError({ reason: String(cause) }), + }) + + // Multi-session channels (izapia) share one webhook URL/secret across + // every configured session — a legacy single-session channel (no + // `sessionIds` set) trusts whatever session sends to it, same as + // before this field existed. + const allowedSessions = channel.sessionIds + for (const event of events) { + if (event.type !== "message.received") continue + if (allowedSessions && event.instanceId && !allowedSessions.includes(event.instanceId)) continue + if (event.message.fromMe) continue + if (!isChatAllowed(channel, event.message.chatId)) continue + const text = event.message.text + if (!text) continue + yield* enqueue({ + agentID: input.agentID, + directory, + channel, + chatId: event.message.chatId, + instanceId: event.instanceId, + text, + }) + } + return { ok: true as const } + }) + + // Raw fetch, not the `izapia()` WaAdapter — listing every session for a + // tenant is an account-level operation (see docs/providers/izapia.md's + // "Modelo de instância/sessão"), outside the WaAdapter contract, which + // only ever operates against one already-known `sid`. + const listIzapiaSessions = Effect.fn("WhatsApp.listIzapiaSessions")(function* (input: { apiKey: string }) { + const response = yield* Effect.tryPromise({ + try: () => + fetch(`${IZAPIA_BASE_URL}/api/v1/sessions/`, { + headers: { authorization: `Bearer ${input.apiKey}` }, + }), + catch: (cause) => new WhatsAppProviderApiError({ reason: String(cause) }), + }) + if (!response.ok) { + return yield* new WhatsAppProviderApiError({ reason: `izapia respondeu ${response.status}` }) + } + const body = yield* Effect.tryPromise({ + try: () => response.json() as Promise, + catch: (cause) => new WhatsAppProviderApiError({ reason: String(cause) }), + }) + const record = body && typeof body === "object" ? (body as Record) : undefined + const list = Array.isArray(body) ? body : Array.isArray(record?.data) ? record.data : undefined + if (!list) return yield* new WhatsAppProviderApiError({ reason: "resposta inesperada da API do izapia" }) + return list + .filter((item): item is Record => !!item && typeof item === "object") + .map((item) => ({ + id: String(item.id ?? ""), + name: typeof item.name === "string" && item.name ? item.name : undefined, + status: String(item.status ?? "unknown"), + jid: typeof item.jid === "string" ? item.jid : undefined, + })) + .filter((session) => session.id) + }) + + // Unlike listIzapiaSessions (account-level, no WaAdapter contract for + // it), listing a session's groups IS part of the contract + // (`groups.list`) — reuse the real, already-tested izapia adapter + // instead of hand-rolling another raw fetch. One session's failure + // (not yet paired, revoked key, ...) doesn't fail the others; a group + // that exists on more than one selected session is deduped by id. + const listIzapiaGroups = Effect.fn("WhatsApp.listIzapiaGroups")(function* (input: { + apiKey: string + sids: string[] + }) { + const byID = new Map() + yield* Effect.forEach( + input.sids, + (sid) => + Effect.tryPromise(() => + createConnector(izapia({ baseUrl: IZAPIA_BASE_URL, apiKey: input.apiKey, sid })).groups.list(), + ).pipe( + Effect.map((groups) => { + for (const group of groups) { + if (byID.has(group.id)) continue + byID.set(group.id, { + id: group.id, + subject: group.subject || group.id, + sessionId: sid, + participantCount: group.participants.length, + }) + } + }), + Effect.tapError((cause) => Effect.logWarning("izapia groups.list failed for session", { sid, cause })), + Effect.ignore, + ), + { concurrency: "unbounded" }, + ) + return Array.from(byID.values()) + }) + + return Service.of({ handleWebhook, listIzapiaSessions, listIzapiaGroups }) + }), +) + +export const node = LayerNode.make({ + service: Service, + layer, + deps: [AgentUI.node], +}) diff --git a/packages/opencode/test/agentui/agentui.test.ts b/packages/opencode/test/agentui/agentui.test.ts index a41ffa469537..0834f0ffc366 100644 --- a/packages/opencode/test/agentui/agentui.test.ts +++ b/packages/opencode/test/agentui/agentui.test.ts @@ -8,7 +8,9 @@ import { InstanceBootstrap } from "../../src/project/bootstrap-service" import { SessionSummary } from "../../src/session/summary" import { LSP } from "../../src/lsp/lsp" import { MCP } from "../../src/mcp" +import { Wildcard } from "@opencode-ai/core/util/wildcard" import { RuntimeFlags } from "@/effect/runtime-flags" +import { Storage } from "@/storage/storage" import { testEffect } from "../lib/effect" // AgentUI.Service now pulls in Session/SessionPrompt/InstanceStore (for the @@ -70,6 +72,40 @@ const noopMcp = Layer.succeed( ) const noopRuntimeFlags = RuntimeFlags.layer({ experimentalEventSystem: true }) +// In-memory stand-in for the audit log's persistence (see +// AgentUI.Service.logAudit/listAudit) — the real Storage.node does actual +// filesystem I/O and pulls in Git.node (real `git` calls for its migration +// step), neither of which anything below actually needs to exercise. +const storageState = new Map() +function storageRead(key: string[]) { + return storageState.has(key.join("/")) + ? Effect.succeed(storageState.get(key.join("/")) as T) + : Effect.fail(new Storage.NotFoundError({ message: "not found" })) +} +function storageUpdate(key: string[], fn: (draft: T) => void) { + return Effect.sync(() => { + const current = storageState.get(key.join("/")) as T + fn(current) + return current + }) +} +const noopStorage = Layer.succeed( + Storage.Service, + Storage.Service.of({ + read: storageRead, + write: (key, content) => + Effect.sync(() => { + storageState.set(key.join("/"), content) + }), + update: storageUpdate, + remove: (key) => + Effect.sync(() => { + storageState.delete(key.join("/")) + }), + list: () => Effect.succeed([]), + }), +) + const it = testEffect( LayerNode.compile(AgentUI.node, [ [InstanceStore.bootstrapNode, noopBootstrap], @@ -78,6 +114,7 @@ const it = testEffect( [MCP.node, noopMcp], [RuntimeFlags.node, noopRuntimeFlags], [LocationServiceMap.node, locationServiceMapLayer], + [Storage.node, noopStorage], ]), ) @@ -232,12 +269,29 @@ it.instance("generateDraft() fails with AgentUIGenerateFailedError when no provi }), ) -it.instance("sessionPermission() denies bash/edit/write/task/external_directory", () => +it.instance( + "sessionPermission() denies everything by default, including tools outside the old bash/edit/write/task/external_directory list", + () => + Effect.gen(function* () { + const svc = yield* AgentUI.Service + const ruleset = svc.sessionPermission() + // A wildcard deny, not a per-category list: anything the model tries + // that isn't bash/edit/write/task/external_directory used to fall + // through to the *default* permission action ("ask"), which hangs a + // channel dispatch forever (no human to answer it) — see + // agentui/index.ts's sessionPermission for the incident this fixed. + for (const permission of ["bash", "edit", "write", "task", "external_directory", "todowrite", "webfetch", "lsp"]) { + const rule = ruleset.findLast((r) => Wildcard.match(permission, r.permission)) + expect(rule?.action).toBe("deny") + } + }), +) + +it.instance("sessionPermission() still allows an agent's configured MCP servers", () => Effect.gen(function* () { const svc = yield* AgentUI.Service - const ruleset = svc.sessionPermission() - for (const permission of ["bash", "edit", "write", "task", "external_directory"]) { - expect(ruleset.some((rule) => rule.permission === permission && rule.action === "deny")).toBe(true) - } + const ruleset = svc.sessionPermission(["my-server"]) + const rule = ruleset.findLast((r) => Wildcard.match("my-server_some_tool", r.permission)) + expect(rule?.action).toBe("allow") }), ) diff --git a/packages/opencode/test/server/httpapi-exercise/dsl.ts b/packages/opencode/test/server/httpapi-exercise/dsl.ts index 60d41576f04b..d4aa4ed39731 100644 --- a/packages/opencode/test/server/httpapi-exercise/dsl.ts +++ b/packages/opencode/test/server/httpapi-exercise/dsl.ts @@ -96,13 +96,16 @@ class ScenarioBuilder { } status( - status = 200, + status: number | number[] = 200, inspect?: (ctx: SeededContext, result: CallResult) => Effect.Effect, compare: Comparison = "status", ) { + const statuses = Array.isArray(status) ? status : [status] return this.done(compare, (ctx, result) => Effect.gen(function* () { - if (result.status !== status) throw new Error(`expected ${status}, got ${result.status}: ${result.text}`) + if (!statuses.includes(result.status)) { + throw new Error(`expected ${statuses.join(" or ")}, got ${result.status}: ${result.text}`) + } if (inspect) yield* inspect(ctx, result) }), ) diff --git a/packages/opencode/test/server/httpapi-exercise/index.ts b/packages/opencode/test/server/httpapi-exercise/index.ts index 4784803a69e0..be71d4874b12 100644 --- a/packages/opencode/test/server/httpapi-exercise/index.ts +++ b/packages/opencode/test/server/httpapi-exercise/index.ts @@ -1885,6 +1885,13 @@ const scenarios: Scenario[] = [ body: { description: "assistente que ajuda a programar em python" }, })) .status(500, undefined, "status"), + http.protected + .get("/agentui/{id}/audit", "agentui.audit") + .at((ctx) => ({ + path: route("/agentui/{id}/audit", { id: "httpapi-test-agent" }), + headers: ctx.headers(), + })) + .json(200, array), // --- Batuta (external-agent orchestration) --- http.protected @@ -2188,6 +2195,45 @@ const scenarios: Scenario[] = [ .json(200, (body) => { check(body === true, "telegram disconnect should return true") }), + + // --- Tunnel --- + http.protected.get("/tunnel/status", "tunnel.status").json(200, object), + http.protected.get("/tunnel/tailscale", "tunnel.tailscale").json(200, object), + http.protected.post("/tunnel/stop", "tunnel.stop").mutating().json(200, object), + http.protected + .post("/tunnel/start", "tunnel.start") + .at((ctx) => ({ + path: "/tunnel/start", + headers: ctx.headers(), + body: { port: 4096 }, + })) + .status([200, 500], undefined, "status"), + + // --- WhatsApp --- + http.public + .post("/whatsapp/izapia/groups", "whatsapp.izapiaGroups") + .at((ctx) => ({ + path: "/whatsapp/izapia/groups", + headers: ctx.headers(), + body: { apiKey: "test-api-key", sids: [] }, + })) + .json(200, array), + http.public + .post("/whatsapp/izapia/sessions", "whatsapp.izapiaSessions") + .at((ctx) => ({ + path: "/whatsapp/izapia/sessions", + headers: ctx.headers(), + body: { apiKey: "invalid-key" }, + })) + .status(500, undefined, "status"), + http.public + .post("/whatsapp/webhook/{agentId}/{secret}", "whatsapp.webhook") + .at((ctx) => ({ + path: route("/whatsapp/webhook/{agentId}/{secret}", { agentId: "missing-agent", secret: "secret" }), + headers: ctx.headers(), + body: {}, + })) + .status(500, undefined, "status"), ] const llmScenarios = new Set([ diff --git a/packages/opencode/test/session/prompt.test.ts b/packages/opencode/test/session/prompt.test.ts index d450eded78e0..e8d65add4472 100644 --- a/packages/opencode/test/session/prompt.test.ts +++ b/packages/opencode/test/session/prompt.test.ts @@ -565,15 +565,26 @@ it.instance("loop calls LLM and returns assistant message", () => }), ) -// Skipped: intermittently fails in CI (and reproduces locally in isolation) with -// `InterruptError: All fibers interrupted without error`, thrown from this test's own -// `.instance` scope teardown (tmpdir + git init + LSP boot + mock LLM server, all -// released together) racing against the still-hanging `llm.hang()` (Stream.never-backed) -// fiber's interruption. Tried wrapping the explicit `Fiber.interrupt(fiber)` below in -// `Effect.ignore` — did not fix it, so the error isn't coming from that call. Root cause -// needs someone with more Effect-runtime/Scope-finalizer context to trace which finalizer -// is responsible. See https://github.com/alltomatos/opencode/issues/181 for the full -// investigation before re-enabling. +// Skipped: fails on `dev` HEAD itself (independent of any feature branch — +// confirmed on 5+ consecutive `dev` CI runs since 2026-09-06), always with +// the same InterruptError signature ("All fibers interrupted without +// error"), at a tight ~20.5s-21.1s cluster in CI. That clustering is too +// tight for generic CI-load contention (compare the subprocess-timeout +// flakes fixed alongside this, which varied by hundreds of ms around their +// bound). Two independent investigations, two different leads, neither +// confirmed yet: +// - #185: suspects a fixed idle/read timeout somewhere in the HTTP client +// stack firing on the deliberately-hung SSE stream (`llm.hang()`), not +// an actual hang in prompt.loop. +// - #181: reproduces locally in isolation too, and traces the +// InterruptError to this test's own `.instance` scope teardown (tmpdir + +// git init + LSP boot + mock LLM server, all released together) racing +// against the still-hanging `llm.hang()` fiber's interruption. Wrapping +// the explicit `Fiber.interrupt(fiber)` below in `Effect.ignore` did not +// fix it, so the error isn't coming from that call — needs someone with +// more Effect-runtime/Scope-finalizer context to trace which finalizer +// is responsible. +// See both issues for the full investigations before re-enabling. withMcpInstructions.instance.skip( "loop includes MCP instructions in model system context", () => @@ -597,14 +608,7 @@ withMcpInstructions.instance.skip( expect(body).toContain("Use lookup before mutate.") yield* Fiber.interrupt(fiber) }), - // Was 15s: this is a real `.instance` test (tmpdir + git init + LSP - // location-services boot, not mocked), and that setup overhead alone can - // exceed 15s under load before prompt.loop's own 10s-budgeted wait - // (llm.wait(1), below) ever gets a chance to run — surfacing as a bare - // bun-test timeout instead of that wait's own distinct error message. - // Confirmed by reproducing this test's timeout locally, consistently, - // outside of any CI load. See 2026-09-08 CI investigation. - 40_000, + 60_000, ) it.instance("legacy prompt emits message events without session.next events", () => diff --git a/packages/opencode/test/session/snapshot-tool-race.test.ts b/packages/opencode/test/session/snapshot-tool-race.test.ts index a88562d25c23..ca6475c8d4da 100644 --- a/packages/opencode/test/session/snapshot-tool-race.test.ts +++ b/packages/opencode/test/session/snapshot-tool-race.test.ts @@ -29,6 +29,7 @@ import { testEffect } from "../lib/effect" import { TestLLMServer } from "../lib/llm-server" import { LSP } from "@/lsp/lsp" +import { LocationServiceMap, locationServiceMapLayer } from "@opencode-ai/core/location-services" import { MCP } from "../../src/mcp" import { CrossSpawnSpawner } from "@opencode-ai/core/cross-spawn-spawner" import { RuntimeFlags } from "@/effect/runtime-flags" @@ -91,12 +92,14 @@ const root = LayerNode.group([ SessionSummary.node, Database.node, CrossSpawnSpawner.node, + LocationServiceMap.node, LayerNode.make({ service: TestLLMServer, layer: TestLLMServer.layer, deps: [] }), ]) const it = testEffect( AppNodeBuilder.build(root, [ [MCP.node, mcp], [LSP.node, lsp], + [LocationServiceMap.node, locationServiceMapLayer], [RuntimeFlags.node, RuntimeFlags.layer({ experimentalEventSystem: true })], [InstanceStore.bootstrapNode, bootstrap], ]), diff --git a/packages/opencode/test/whatsapp/whatsapp.test.ts b/packages/opencode/test/whatsapp/whatsapp.test.ts new file mode 100644 index 000000000000..6330d204d736 --- /dev/null +++ b/packages/opencode/test/whatsapp/whatsapp.test.ts @@ -0,0 +1,143 @@ +import { expect } from "bun:test" +import { LayerNode } from "@opencode-ai/core/effect/layer-node" +import { LocationServiceMap, locationServiceMapLayer } from "@opencode-ai/core/location-services" +import { Effect, Exit, Layer } from "effect" +import { AgentUI } from "../../src/agentui/index" +import { WhatsApp } from "../../src/whatsapp/index" +import { InstanceStore } from "../../src/project/instance-store" +import { InstanceBootstrap } from "../../src/project/bootstrap-service" +import { SessionSummary } from "../../src/session/summary" +import { LSP } from "../../src/lsp/lsp" +import { MCP } from "../../src/mcp" +import { RuntimeFlags } from "@/effect/runtime-flags" +import { testEffect } from "../lib/effect" + +// Same wide-dependency-tree stubbing as test/agentui/agentui.test.ts (WhatsApp.Service +// depends on AgentUI.Service, which drags in Session/SessionPrompt/InstanceStore) — see that +// file's comment for why these are noop/minimal rather than real. +const noopBootstrap = Layer.succeed(InstanceBootstrap.Service, InstanceBootstrap.Service.of({ run: Effect.void })) +const noopSummary = Layer.succeed( + SessionSummary.Service, + SessionSummary.Service.of({ summarize: () => Effect.void, diff: () => Effect.succeed([]), computeDiff: () => Effect.succeed([]) }), +) +const noopLsp = Layer.succeed( + LSP.Service, + LSP.Service.of({ + init: () => Effect.void, + status: () => Effect.succeed([]), + hasClients: () => Effect.succeed(false), + touchFile: () => Effect.void, + diagnostics: () => Effect.succeed({}), + hover: () => Effect.succeed(undefined), + definition: () => Effect.succeed([]), + references: () => Effect.succeed([]), + implementation: () => Effect.succeed([]), + documentSymbol: () => Effect.succeed([]), + workspaceSymbol: () => Effect.succeed([]), + prepareCallHierarchy: () => Effect.succeed([]), + incomingCalls: () => Effect.succeed([]), + outgoingCalls: () => Effect.succeed([]), + }), +) +const noopMcp = Layer.succeed( + MCP.Service, + MCP.Service.of({ + status: () => Effect.succeed({}), + clients: () => Effect.succeed({}), + instructions: () => Effect.succeed([]), + tools: () => Effect.succeed({}), + prompts: () => Effect.succeed({}), + resources: () => Effect.succeed({}), + resourceTemplates: () => Effect.succeed({}), + add: () => Effect.succeed({ status: { status: "disabled" as const } }), + connect: () => Effect.void, + disconnect: () => Effect.void, + remove: () => Effect.void, + serverCatalog: () => Effect.succeed({ tools: [], prompts: [], resources: [] }), + getPrompt: () => Effect.succeed(undefined), + readResource: () => Effect.succeed(undefined), + startAuth: () => Effect.die("unexpected MCP auth in whatsapp tests"), + authenticate: () => Effect.die("unexpected MCP auth in whatsapp tests"), + finishAuth: () => Effect.die("unexpected MCP auth in whatsapp tests"), + removeAuth: () => Effect.void, + supportsOAuth: () => Effect.succeed(false), + hasStoredTokens: () => Effect.succeed(false), + getAuthStatus: () => Effect.succeed("not_authenticated" as const), + }), +) +const noopRuntimeFlags = RuntimeFlags.layer({ experimentalEventSystem: true }) + +const it = testEffect( + LayerNode.compile(LayerNode.group([WhatsApp.node, AgentUI.node]), [ + [InstanceStore.bootstrapNode, noopBootstrap], + [SessionSummary.node, noopSummary], + [LSP.node, noopLsp], + [MCP.node, noopMcp], + [RuntimeFlags.node, noopRuntimeFlags], + [LocationServiceMap.node, locationServiceMapLayer], + ]), +) + +function agent(overrides: { id?: string } = {}) { + return { + id: overrides.id ?? "agent-1", + name: "Agent 1", + personality: "You are a helpful support agent.", + model: "openrouter/a", + channels: [] as any[], + commandTriggers: ["!"], + ragSources: [], + guardrails: { enabled: true, level: "basic" as const }, + } +} + +it.instance("handleWebhook() fails with AgentUINotFoundError for an unknown agent id", () => + Effect.gen(function* () { + const svc = yield* WhatsApp.Service + const exit = yield* svc + .handleWebhook({ agentID: "definitely-not-here", secret: "s", body: {}, headers: {} }) + .pipe(Effect.exit) + expect(Exit.isFailure(exit)).toBe(true) + }), +) + +it.instance("handleWebhook() fails with WhatsAppChannelNotConfiguredError when the agent has no whatsapp channel", () => + Effect.gen(function* () { + const agentUI = yield* AgentUI.Service + const created = agent({ id: "no-whatsapp-channel" }) + yield* agentUI.add(created) + + const svc = yield* WhatsApp.Service + const exit = yield* svc.handleWebhook({ agentID: created.id, secret: "s", body: {}, headers: {} }).pipe(Effect.exit) + expect(Exit.isFailure(exit)).toBe(true) + + yield* agentUI.remove(created.id) + }), +) + +it.instance("handleWebhook() fails with WhatsAppInvalidWebhookError on secret mismatch", () => + Effect.gen(function* () { + const agentUI = yield* AgentUI.Service + const created = { + ...agent({ id: "wrong-secret" }), + channels: [ + { + type: "whatsapp" as const, + provider: "waha" as const, + config: { baseUrl: "http://localhost:3000", apiKey: "k" }, + directory: "/tmp/does-not-matter", + webhookSecret: "correct-secret", + }, + ], + } + yield* agentUI.add(created) + + const svc = yield* WhatsApp.Service + const exit = yield* svc + .handleWebhook({ agentID: created.id, secret: "wrong-secret", body: {}, headers: {} }) + .pipe(Effect.exit) + expect(Exit.isFailure(exit)).toBe(true) + + yield* agentUI.remove(created.id) + }), +) diff --git a/packages/sdk/js/src/v2/gen/sdk.gen.ts b/packages/sdk/js/src/v2/gen/sdk.gen.ts index 91a07d32da3a..1425b4d75e48 100644 --- a/packages/sdk/js/src/v2/gen/sdk.gen.ts +++ b/packages/sdk/js/src/v2/gen/sdk.gen.ts @@ -7,6 +7,8 @@ import type { AgentuiAddErrors, AgentuiAddResponses, AgentUiAgent, + AgentuiAuditErrors, + AgentuiAuditResponses, AgentuiGenerateErrors, AgentuiGenerateResponses, AgentuiGetErrors, @@ -483,6 +485,20 @@ import type { VcsGetResponses, VcsStatusErrors, VcsStatusResponses, + TunnelStartErrors, + TunnelStartResponses, + TunnelStatusErrors, + TunnelStatusResponses, + TunnelStopErrors, + TunnelStopResponses, + TunnelTailscaleErrors, + TunnelTailscaleResponses, + WhatsappIzapiaGroupsErrors, + WhatsappIzapiaGroupsResponses, + WhatsappIzapiaSessionsErrors, + WhatsappIzapiaSessionsResponses, + WhatsappWebhookErrors, + WhatsappWebhookResponses, WorktreeCreateErrors, WorktreeCreateInput, WorktreeCreateResponses, @@ -2243,6 +2259,38 @@ export class Agentui extends HeyApiClient { }) } + /** + * Get an AgentUI agent's audit log + * + * Lists recent turns (incoming message + the agent's reply) across every channel this agent is reachable on, newest first. + */ + public audit( + parameters: { + id: string + directory?: string + workspace?: string + }, + options?: Options, + ) { + const params = buildClientParams( + [parameters], + [ + { + args: [ + { in: "path", key: "id" }, + { in: "query", key: "directory" }, + { in: "query", key: "workspace" }, + ], + }, + ], + ) + return (options?.client ?? this.client).get({ + url: "/agentui/{id}/audit", + ...options, + ...params, + }) + } + /** * Get an AgentUI agent * @@ -6503,6 +6551,175 @@ export class Tui extends HeyApiClient { } } +export class Whatsapp extends HeyApiClient { + /** + * Receive a WhatsApp webhook for an AgentUI agent + * + * Inbound webhook endpoint for the agent's configured WhatsApp channel (via waconector). Never call this directly — it's the URL configured on the WhatsApp gateway itself. + */ + public webhook( + parameters: { + agentId: string + secret: string + directory?: string + workspace?: string + body?: unknown + }, + options?: Options, + ) { + const params = buildClientParams( + [parameters], + [ + { + args: [ + { in: "path", key: "agentId" }, + { in: "path", key: "secret" }, + { in: "query", key: "directory" }, + { in: "query", key: "workspace" }, + { key: "body", map: "body" }, + ], + }, + ], + ) + return (options?.client ?? this.client).post({ + url: "/whatsapp/webhook/{agentId}/{secret}", + ...options, + ...params, + headers: { + "Content-Type": "application/json", + ...options?.headers, + ...params.headers, + }, + }) + } + + /** + * List izapia sessions + * + * Lists the WhatsApp sessions already created for the tenant that owns the given izapia API key. + */ + public izapiaSessions( + parameters: { + apiKey: string + }, + options?: Options, + ) { + const params = buildClientParams( + [parameters], + [ + { + args: [{ in: "body", key: "apiKey" }], + }, + ], + ) + return (options?.client ?? this.client).post< + WhatsappIzapiaSessionsResponses, + WhatsappIzapiaSessionsErrors, + ThrowOnError + >({ + url: "/whatsapp/izapia/sessions", + ...options, + ...params, + headers: { + "Content-Type": "application/json", + ...options?.headers, + ...params.headers, + }, + }) + } + + /** + * List izapia groups + * + * Lists WhatsApp groups across the given izapia sessions, deduped by group id. + */ + public izapiaGroups( + parameters: { + apiKey: string + sids: Array + }, + options?: Options, + ) { + const params = buildClientParams( + [parameters], + [ + { + args: [ + { in: "body", key: "apiKey" }, + { in: "body", key: "sids" }, + ], + }, + ], + ) + return (options?.client ?? this.client).post({ + url: "/whatsapp/izapia/groups", + ...options, + ...params, + headers: { + "Content-Type": "application/json", + ...options?.headers, + ...params.headers, + }, + }) + } +} + +export class Tunnel extends HeyApiClient { + /** + * Start public tunnel + * + * Starts a cloudflared quick tunnel exposing this server's given local port publicly. + */ + public start( + parameters: { + port: number + }, + options?: Options, + ) { + const params = buildClientParams([parameters], [{ args: [{ in: "body", key: "port" }] }]) + return (options?.client ?? this.client).post({ + url: "/tunnel/start", + ...options, + ...params, + headers: { + "Content-Type": "application/json", + ...options?.headers, + ...params.headers, + }, + }) + } + + /** + * Get tunnel status + */ + public status(options?: Options) { + return (options?.client ?? this.client).get({ + url: "/tunnel/status", + ...options, + }) + } + + /** + * Stop public tunnel + */ + public stop(options?: Options) { + return (options?.client ?? this.client).post({ + url: "/tunnel/stop", + ...options, + }) + } + + /** + * Detect local Tailscale IP + */ + public tailscale(options?: Options) { + return (options?.client ?? this.client).get({ + url: "/tunnel/tailscale", + ...options, + }) + } +} + export class Health extends HeyApiClient { /** * Check server health @@ -8724,6 +8941,16 @@ export class OpencodeClient extends HeyApiClient { return (this._tui ??= new Tui({ client: this.client })) } + private _whatsapp?: Whatsapp + get whatsapp(): Whatsapp { + return (this._whatsapp ??= new Whatsapp({ client: this.client })) + } + + private _tunnel?: Tunnel + get tunnel(): Tunnel { + return (this._tunnel ??= new Tunnel({ client: this.client })) + } + private _v2?: V2 get v2(): V2 { return (this._v2 ??= new V2({ client: this.client })) diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index 4d39d6293649..76d7104bdc14 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -1977,12 +1977,41 @@ export type ComboConfig = { [key: string]: Combo } -export type AgentUiChannelBinding = { +export type AgentUiTelegramChannelBinding = { type: "telegram" token?: string directory?: string } +export type AgentUiWhatsAppChannelBinding = { + type: "whatsapp" + /** + * Which unofficial WhatsApp API this channel connects through (see waconector). + */ + provider: "waha" | "evolution" | "zapi" | "uazapi" | "whapi" | "wuzapi" | "quepasa" | "wppconnect" | "izapia" + /** + * Provider-specific connection fields (e.g. baseUrl+apiKey for WAHA, instanceId+token for Z-API). Shape depends on `provider`. + */ + config: { + [key: string]: string + } + /** + * Session IDs this channel listens on, for providers with multiple sessions per tenant (izapia). Absent means single-session (see config.sid). + */ + sessionIds?: Array + /** + * WhatsApp group JIDs this agent may respond in, in addition to direct messages. Empty/absent means direct messages only. + */ + allowedGroups?: Array + directory?: string + /** + * Random per-channel secret embedded in the webhook URL — authenticates inbound webhook calls from the provider. + */ + webhookSecret: string +} + +export type AgentUiChannelBinding = AgentUiTelegramChannelBinding | AgentUiWhatsAppChannelBinding + export type AgentUiRagSource = { id: string kind: "file" | "text" | "url" @@ -2031,6 +2060,10 @@ export type AgentUiAgent = { */ ragSources: Array guardrails: AgentUiGuardrails + /** + * Names of MCP servers this agent is allowed to call tools from. Empty/absent means none. + */ + mcpServers?: Array enabled?: boolean } @@ -2891,6 +2924,21 @@ export type EventTuiSessionSelect = { } } +export type WhatsAppChannelNotConfiguredError = { + _tag: "WhatsAppChannelNotConfiguredError" + id: string +} + +export type WhatsAppInvalidWebhookError = { + _tag: "WhatsAppInvalidWebhookError" + reason: string +} + +export type WhatsAppProviderApiError = { + _tag: "WhatsAppProviderApiError" + reason: string +} + export type Workspace = { id: string type: string @@ -8330,6 +8378,46 @@ export type AgentuiGetResponses = { export type AgentuiGetResponse = AgentuiGetResponses[keyof AgentuiGetResponses] +export type AgentUiAuditEntry = { + id: string + timestamp: number + channel: "whatsapp" | "telegram" | "sandbox" + chatKey: string + incoming: string + outgoing: string + blocked: boolean +} + +export type AgentuiAuditData = { + body?: never + path: { + id: string + } + query?: { + directory?: string + workspace?: string + } + url: "/agentui/{id}/audit" +} + +export type AgentuiAuditErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type AgentuiAuditError = AgentuiAuditErrors[keyof AgentuiAuditErrors] + +export type AgentuiAuditResponses = { + /** + * Audit log entries, newest first + */ + 200: Array +} + +export type AgentuiAuditResponse = AgentuiAuditResponses[keyof AgentuiAuditResponses] + export type AgentuiGenerateData = { body?: { description: string @@ -12613,6 +12701,239 @@ export type TuiControlResponseResponses = { export type TuiControlResponseResponse = TuiControlResponseResponses[keyof TuiControlResponseResponses] +export type WhatsappWebhookData = { + body?: unknown + path: { + agentId: string + secret: string + } + query?: { + directory?: string + workspace?: string + } + url: "/whatsapp/webhook/{agentId}/{secret}" +} + +export type WhatsappWebhookErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * AgentUINotFoundError | WhatsAppChannelNotConfiguredError | WhatsAppInvalidWebhookError + */ + 500: AgentUiNotFoundError | WhatsAppChannelNotConfiguredError | WhatsAppInvalidWebhookError +} + +export type WhatsappWebhookError = WhatsappWebhookErrors[keyof WhatsappWebhookErrors] + +export type WhatsappWebhookResponses = { + /** + * Webhook processed + */ + 200: { + ok: true + } +} + +export type WhatsappWebhookResponse = WhatsappWebhookResponses[keyof WhatsappWebhookResponses] + +export type IzapiaSession = { + id: string + name?: string + status: string + jid?: string +} + +export type WhatsappIzapiaSessionsData = { + body?: { + apiKey: string + } + path?: never + query?: never + url: "/whatsapp/izapia/sessions" +} + +export type WhatsappIzapiaSessionsErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * WhatsAppProviderApiError + */ + 500: WhatsAppProviderApiError +} + +export type WhatsappIzapiaSessionsError = WhatsappIzapiaSessionsErrors[keyof WhatsappIzapiaSessionsErrors] + +export type WhatsappIzapiaSessionsResponses = { + /** + * Sessions for this izapia tenant + */ + 200: Array +} + +export type WhatsappIzapiaSessionsResponse = WhatsappIzapiaSessionsResponses[keyof WhatsappIzapiaSessionsResponses] + +export type IzapiaGroup = { + id: string + subject: string + sessionId: string + participantCount: number +} + +export type WhatsappIzapiaGroupsData = { + body: { + apiKey: string + sids: Array + } + path?: never + query?: never + url: "/whatsapp/izapia/groups" +} + +export type WhatsappIzapiaGroupsErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type WhatsappIzapiaGroupsError = WhatsappIzapiaGroupsErrors[keyof WhatsappIzapiaGroupsErrors] + +export type WhatsappIzapiaGroupsResponses = { + /** + * Groups across the given izapia sessions + */ + 200: Array +} + +export type WhatsappIzapiaGroupsResponse = WhatsappIzapiaGroupsResponses[keyof WhatsappIzapiaGroupsResponses] + +export type TunnelStatus = { + running: boolean + url?: string +} + +export type TunnelError = { + _tag: "TunnelError" + reason: string +} + +export type TunnelStartData = { + body: { + port: number + } + path?: never + query?: never + url: "/tunnel/start" +} + +export type TunnelStartErrors = { + /** + * Bad request + */ + 400: BadRequestError + /** + * TunnelError + */ + 500: TunnelError +} + +export type TunnelStartError = TunnelStartErrors[keyof TunnelStartErrors] + +export type TunnelStartResponses = { + /** + * Tunnel started (or already running) + */ + 200: TunnelStatus +} + +export type TunnelStartResponse = TunnelStartResponses[keyof TunnelStartResponses] + +export type TunnelStatusData = { + body?: never + path?: never + query?: never + url: "/tunnel/status" +} + +export type TunnelStatusErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type TunnelStatusError = TunnelStatusErrors[keyof TunnelStatusErrors] + +export type TunnelStatusResponses = { + /** + * Current tunnel status + */ + 200: TunnelStatus +} + +export type TunnelStatusResponse = TunnelStatusResponses[keyof TunnelStatusResponses] + +export type TunnelStopData = { + body?: never + path?: never + query?: never + url: "/tunnel/stop" +} + +export type TunnelStopErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type TunnelStopError = TunnelStopErrors[keyof TunnelStopErrors] + +export type TunnelStopResponses = { + /** + * Tunnel stopped + */ + 200: { + ok: true + } +} + +export type TunnelStopResponse = TunnelStopResponses[keyof TunnelStopResponses] + +export type TunnelTailscaleStatus = { + available: boolean + ip?: string +} + +export type TunnelTailscaleData = { + body?: never + path?: never + query?: never + url: "/tunnel/tailscale" +} + +export type TunnelTailscaleErrors = { + /** + * Bad request + */ + 400: BadRequestError +} + +export type TunnelTailscaleError = TunnelTailscaleErrors[keyof TunnelTailscaleErrors] + +export type TunnelTailscaleResponses = { + /** + * Local Tailscale IP, if available + */ + 200: TunnelTailscaleStatus +} + +export type TunnelTailscaleResponse = TunnelTailscaleResponses[keyof TunnelTailscaleResponses] + export type ExperimentalWorkspaceAdapterListData = { body?: never path?: never