diff --git a/Dockerfile b/Dockerfile index c8f6a6f46..4643d8b65 100644 --- a/Dockerfile +++ b/Dockerfile @@ -18,6 +18,15 @@ RUN apt-get update \ && apt-get install -y --no-install-recommends curl bash \ && rm -rf /var/lib/apt/lists/* +# drop npm and corepack +RUN rm -rf /usr/local/lib/node_modules/npm \ + && rm -rf /usr/local/lib/node_modules/corepack \ + && rm -rf /usr/local/bin/npm \ + && rm -rf /usr/local/bin/npx \ + && rm -rf /usr/local/bin/corepack \ + && rm -rf /root/.npm \ + && rm -rf /root/.node-gyp + WORKDIR /app # Copy apps diff --git a/apps/client/package.json b/apps/client/package.json index e5bb5ad5a..cca0ef4be 100644 --- a/apps/client/package.json +++ b/apps/client/package.json @@ -52,7 +52,7 @@ "mantine-form-zod-resolver": "1.3.0", "mermaid": "11.16.1", "mitt": "3.0.1", - "nanoid": "3.3.17", + "nanoid": "3.3.18", "posthog-js": "1.391.2", "react": "19.2.7", "react-clear-modal": "^2.0.18", diff --git a/apps/client/public/locales/de-DE/translation.json b/apps/client/public/locales/de-DE/translation.json index f067ecc27..084c92ef5 100644 --- a/apps/client/public/locales/de-DE/translation.json +++ b/apps/client/public/locales/de-DE/translation.json @@ -696,7 +696,7 @@ "Upgrade your plan": "Upgrade Ihres Plans", "Available with a paid license": "Verfügbar mit einer kostenpflichtigen Lizenz", "Upgrade your license tier.": "Stufen Sie Ihre Lizenz hoch.", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "KI ist nur in der Docmost Enterprise-Edition verfügbar. Kontaktieren Sie sales@docmost.com.", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "KI ist in den kostenpflichtigen Docmost-Editionen verfügbar. Kontaktieren Sie sales@docmost.com.", "AI & MCP": "KI & MCP", "AI": "KI", "MCP": "MCP", diff --git a/apps/client/public/locales/en-US/translation.json b/apps/client/public/locales/en-US/translation.json index 03e10c53e..e5768c7e4 100644 --- a/apps/client/public/locales/en-US/translation.json +++ b/apps/client/public/locales/en-US/translation.json @@ -698,7 +698,7 @@ "Upgrade your plan": "Upgrade your plan", "Available with a paid license": "Available with a paid license", "Upgrade your license tier.": "Upgrade your license tier.", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "AI is available in the Docmost paid editions. Contact sales@docmost.com.", "AI & MCP": "AI & MCP", "AI": "AI", "MCP": "MCP", @@ -1302,5 +1302,11 @@ "Error loading attachments.": "Error loading attachments.", "No attachments on this page yet.": "No attachments on this page yet.", "Uploaded by {{name}}": "Uploaded by {{name}}", - "Download {{name}}": "Download {{name}}" + "Download {{name}}": "Download {{name}}", + "Workspace knowledge only": "Workspace knowledge only", + "Restrict AI Chat to answering from your workspace pages and uploaded files only. It will not use outside knowledge.": "Restrict AI Chat to answering from your workspace pages and uploaded files only. It will not use outside knowledge.", + "Toggle workspace knowledge only": "Toggle workspace knowledge only", + "Read-only mode": "Read-only mode", + "AI Chat can search and read workspace content, but cannot create or edit pages.": "AI Chat can search and read workspace content, but cannot create or edit pages.", + "Toggle AI Chat read-only mode": "Toggle AI Chat read-only mode" } diff --git a/apps/client/public/locales/es-ES/translation.json b/apps/client/public/locales/es-ES/translation.json index fd834a2c6..fb5364725 100644 --- a/apps/client/public/locales/es-ES/translation.json +++ b/apps/client/public/locales/es-ES/translation.json @@ -696,7 +696,7 @@ "Upgrade your plan": "Mejora tu plan", "Available with a paid license": "Disponible con una licencia de pago", "Upgrade your license tier.": "Mejora el nivel de tu licencia.", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "La IA solo está disponible en la edición empresarial de Docmost. Contacte con sales@docmost.com.", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "La IA está disponible en las ediciones de pago de Docmost. Contacte con sales@docmost.com.", "AI & MCP": "IA y MCP", "AI": "IA", "MCP": "MCP", diff --git a/apps/client/public/locales/fr-FR/translation.json b/apps/client/public/locales/fr-FR/translation.json index 04ebbc6ad..e9fbeed06 100644 --- a/apps/client/public/locales/fr-FR/translation.json +++ b/apps/client/public/locales/fr-FR/translation.json @@ -696,7 +696,7 @@ "Upgrade your plan": "Mettez à niveau votre forfait", "Available with a paid license": "Disponible avec une licence payante", "Upgrade your license tier.": "Mettez à niveau votre niveau de licence.", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "L'IA n'est disponible que dans l'édition Entreprise de Docmost. Contactez sales@docmost.com.", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "L'IA est disponible dans les éditions payantes de Docmost. Contactez sales@docmost.com.", "AI & MCP": "IA & MCP", "AI": "IA", "MCP": "MCP", diff --git a/apps/client/public/locales/it-IT/translation.json b/apps/client/public/locales/it-IT/translation.json index e3aaa82ce..81eb1727f 100644 --- a/apps/client/public/locales/it-IT/translation.json +++ b/apps/client/public/locales/it-IT/translation.json @@ -696,7 +696,7 @@ "Upgrade your plan": "Aggiorna il tuo piano", "Available with a paid license": "Disponibile con una licenza a pagamento", "Upgrade your license tier.": "Aggiorna il livello della tua licenza.", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "L'IA è disponibile solo nell'edizione Enterprise di Docmost. Contatta sales@docmost.com.", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "L'IA è disponibile nelle edizioni a pagamento di Docmost. Contatta sales@docmost.com.", "AI & MCP": "IA e MCP", "AI": "IA", "MCP": "MCP", diff --git a/apps/client/public/locales/ja-JP/translation.json b/apps/client/public/locales/ja-JP/translation.json index e408bfda8..c1bfa1652 100644 --- a/apps/client/public/locales/ja-JP/translation.json +++ b/apps/client/public/locales/ja-JP/translation.json @@ -696,7 +696,7 @@ "Upgrade your plan": "プランをアップグレードする", "Available with a paid license": "有料ライセンスで利用可能", "Upgrade your license tier.": "ライセンスタイアをアップグレードしてください。", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI は Docmost のエンタープライズ版でのみ利用可能です。sales@docmost.com までお問い合わせください。", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "AI は Docmost の有料版で利用可能です。sales@docmost.com までお問い合わせください。", "AI & MCP": "AI と MCP", "AI": "AI", "MCP": "MCP", diff --git a/apps/client/public/locales/ko-KR/translation.json b/apps/client/public/locales/ko-KR/translation.json index fb8e9884a..a7d795454 100644 --- a/apps/client/public/locales/ko-KR/translation.json +++ b/apps/client/public/locales/ko-KR/translation.json @@ -696,7 +696,7 @@ "Upgrade your plan": "요금제를 업그레이드하세요", "Available with a paid license": "유료 라이선스에서만 사용 가능합니다", "Upgrade your license tier.": "라이선스 등급을 업그레이드하세요.", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI는 Docmost 엔터프라이즈 에디션에서만 제공됩니다. sales@docmost.com으로 문의하세요.", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "AI는 Docmost 유료 에디션에서 제공됩니다. sales@docmost.com으로 문의하세요.", "AI & MCP": "AI 및 MCP", "AI": "AI", "MCP": "MCP", diff --git a/apps/client/public/locales/nl-NL/translation.json b/apps/client/public/locales/nl-NL/translation.json index 59c1d7a73..1f1465ab1 100644 --- a/apps/client/public/locales/nl-NL/translation.json +++ b/apps/client/public/locales/nl-NL/translation.json @@ -696,7 +696,7 @@ "Upgrade your plan": "Upgrade je abonnement", "Available with a paid license": "Beschikbaar met een betaalde licentie", "Upgrade your license tier.": "Upgrade je licentieniveau.", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI is alleen beschikbaar in de Docmost Enterprise-editie. Neem contact op met sales@docmost.com.", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "AI is beschikbaar in de betaalde edities van Docmost. Neem contact op met sales@docmost.com.", "AI & MCP": "AI & MCP", "AI": "AI", "MCP": "MCP", diff --git a/apps/client/public/locales/pt-BR/translation.json b/apps/client/public/locales/pt-BR/translation.json index 2e4cd89ef..82f213703 100644 --- a/apps/client/public/locales/pt-BR/translation.json +++ b/apps/client/public/locales/pt-BR/translation.json @@ -696,7 +696,7 @@ "Upgrade your plan": "Faça upgrade do seu plano", "Available with a paid license": "Disponível com uma licença paga", "Upgrade your license tier.": "Faça upgrade do seu nível de licença.", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "A IA está disponível apenas na edição empresarial do Docmost. Contate sales@docmost.com.", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "A IA está disponível nas edições pagas do Docmost. Contate sales@docmost.com.", "AI & MCP": "IA e MCP", "AI": "IA", "MCP": "MCP", diff --git a/apps/client/public/locales/ru-RU/translation.json b/apps/client/public/locales/ru-RU/translation.json index bae44d133..9d4ddc8a6 100644 --- a/apps/client/public/locales/ru-RU/translation.json +++ b/apps/client/public/locales/ru-RU/translation.json @@ -696,7 +696,7 @@ "Upgrade your plan": "Обновите свой тарифный план", "Available with a paid license": "Доступно с платной лицензией", "Upgrade your license tier.": "Обновите уровень вашей лицензии.", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "ИИ доступен только в корпоративной версии Docmost. Свяжитесь по адресу sales@docmost.com.", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "ИИ доступен в платных версиях Docmost. Свяжитесь по адресу sales@docmost.com.", "AI & MCP": "ИИ и MCP", "AI": "ИИ", "MCP": "MCP", diff --git a/apps/client/public/locales/uk-UA/translation.json b/apps/client/public/locales/uk-UA/translation.json index d3dd687ea..be09a646f 100644 --- a/apps/client/public/locales/uk-UA/translation.json +++ b/apps/client/public/locales/uk-UA/translation.json @@ -696,7 +696,7 @@ "Upgrade your plan": "Оновіть свій тарифний план", "Available with a paid license": "Доступно за платною ліцензією", "Upgrade your license tier.": "Оновіть рівень своєї ліцензії.", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "ШІ доступний лише в корпоративній редакції Docmost. Зверніться до sales@docmost.com.", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "ШІ доступний у платних редакціях Docmost. Зверніться до sales@docmost.com.", "AI & MCP": "ШІ та MCP", "AI": "ШІ", "MCP": "MCP", diff --git a/apps/client/public/locales/zh-CN/translation.json b/apps/client/public/locales/zh-CN/translation.json index 97ff9ce85..1b273e71c 100644 --- a/apps/client/public/locales/zh-CN/translation.json +++ b/apps/client/public/locales/zh-CN/translation.json @@ -696,7 +696,7 @@ "Upgrade your plan": "升级您的方案", "Available with a paid license": "需付费许可才可用", "Upgrade your license tier.": "升级您的许可等级。", - "AI is only available in the Docmost enterprise edition. Contact sales@docmost.com.": "AI 仅在 Docmost 企业版中提供。请联系 sales@docmost.com。", + "AI is available in the Docmost paid editions. Contact sales@docmost.com.": "AI 在 Docmost 付费版中提供。请联系 sales@docmost.com。", "AI & MCP": "AI 与 MCP", "AI": "AI", "MCP": "MCP", diff --git a/apps/client/src/ee/ai-chat/components/ai-chat-read-only.tsx b/apps/client/src/ee/ai-chat/components/ai-chat-read-only.tsx new file mode 100644 index 000000000..732800299 --- /dev/null +++ b/apps/client/src/ee/ai-chat/components/ai-chat-read-only.tsx @@ -0,0 +1,74 @@ +import { Badge, Group, Text, Switch, Tooltip } from "@mantine/core"; +import { useAtom } from "jotai"; +import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { updateWorkspace } from "@/features/workspace/services/workspace-service.ts"; +import { notifications } from "@mantine/notifications"; +import { useHasFeature } from "@/ee/hooks/use-feature"; +import { Feature } from "@/ee/features"; +import { useUpgradeLabel } from "@/ee/hooks/use-upgrade-label"; + +export default function AiChatReadOnly() { + const { t } = useTranslation(); + const hasAccess = useHasFeature(Feature.AI_CONTROLS); + + return ( + +
+ + {t("Read-only mode")} + {!hasAccess && ( + + {t("Enterprise")} + + )} + + + {t( + "AI Chat can search and read workspace content, but cannot create or edit pages.", + )} + +
+ + +
+ ); +} + +function AiChatReadOnlyToggle() { + const { t } = useTranslation(); + const [workspace, setWorkspace] = useAtom(workspaceAtom); + const [checked, setChecked] = useState( + workspace?.settings?.ai?.chatReadOnly, + ); + const hasAccess = useHasFeature(Feature.AI_CONTROLS); + const upgradeLabel = useUpgradeLabel(); + + const handleChange = async (event: React.ChangeEvent) => { + const value = event.currentTarget.checked; + try { + const updatedWorkspace = await updateWorkspace({ + aiChatReadOnly: value, + }); + setChecked(value); + setWorkspace(updatedWorkspace); + } catch (err: any) { + notifications.show({ + message: err?.response?.data?.message, + color: "red", + }); + } + }; + + return ( + + + + ); +} diff --git a/apps/client/src/ee/ai-chat/components/ai-chat-workspace-knowledge-only.tsx b/apps/client/src/ee/ai-chat/components/ai-chat-workspace-knowledge-only.tsx new file mode 100644 index 000000000..497a337b4 --- /dev/null +++ b/apps/client/src/ee/ai-chat/components/ai-chat-workspace-knowledge-only.tsx @@ -0,0 +1,74 @@ +import { Badge, Group, Text, Switch, Tooltip } from "@mantine/core"; +import { useAtom } from "jotai"; +import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts"; +import { useState } from "react"; +import { useTranslation } from "react-i18next"; +import { updateWorkspace } from "@/features/workspace/services/workspace-service.ts"; +import { notifications } from "@mantine/notifications"; +import { useHasFeature } from "@/ee/hooks/use-feature"; +import { Feature } from "@/ee/features"; +import { useUpgradeLabel } from "@/ee/hooks/use-upgrade-label"; + +export default function AiChatWorkspaceKnowledgeOnly() { + const { t } = useTranslation(); + const hasAccess = useHasFeature(Feature.AI_CONTROLS); + + return ( + +
+ + {t("Workspace knowledge only")} + {!hasAccess && ( + + {t("Enterprise")} + + )} + + + {t( + "Restrict AI Chat to answering from your workspace pages and uploaded files only. It will not use outside knowledge.", + )} + +
+ + +
+ ); +} + +function AiChatWorkspaceKnowledgeOnlyToggle() { + const { t } = useTranslation(); + const [workspace, setWorkspace] = useAtom(workspaceAtom); + const [checked, setChecked] = useState( + workspace?.settings?.ai?.chatWorkspaceKnowledgeOnly, + ); + const hasAccess = useHasFeature(Feature.AI_CONTROLS); + const upgradeLabel = useUpgradeLabel(); + + const handleChange = async (event: React.ChangeEvent) => { + const value = event.currentTarget.checked; + try { + const updatedWorkspace = await updateWorkspace({ + aiChatWorkspaceKnowledgeOnly: value, + }); + setChecked(value); + setWorkspace(updatedWorkspace); + } catch (err: any) { + notifications.show({ + message: err?.response?.data?.message, + color: "red", + }); + } + }; + + return ( + + + + ); +} diff --git a/apps/client/src/ee/ai-chat/components/chat-empty-state.tsx b/apps/client/src/ee/ai-chat/components/chat-empty-state.tsx index 9583a2f03..423557c53 100644 --- a/apps/client/src/ee/ai-chat/components/chat-empty-state.tsx +++ b/apps/client/src/ee/ai-chat/components/chat-empty-state.tsx @@ -6,7 +6,10 @@ import { IconFileText, } from "@tabler/icons-react"; import { useTranslation } from "react-i18next"; -import ChatInput from "./chat-input"; +import { useAtomValue } from "jotai"; +import { workspaceAtom } from "@/features/user/atoms/current-user-atom.ts"; +import { useRef } from "react"; +import ChatInput, { ChatInputHandle } from "./chat-input"; import type { ChatAttachment, PageMention } from "../types/ai-chat.types"; import classes from "../styles/ai-chat.module.css"; @@ -14,6 +17,7 @@ type Suggestion = { icon: React.ReactNode; text: string; prompt: string; + write?: boolean; }; const SUGGESTIONS: Suggestion[] = [ @@ -26,6 +30,7 @@ const SUGGESTIONS: Suggestion[] = [ icon: , text: "Create a new page", prompt: "Create a new page titled ", + write: true, }, { icon: , @@ -36,6 +41,7 @@ const SUGGESTIONS: Suggestion[] = [ icon: , text: "Update page content", prompt: "Update the page @", + write: true, }, ]; @@ -47,9 +53,13 @@ type Props = { export default function ChatEmptyState({ isStreaming, onSend, onStop }: Props) { const { t } = useTranslation(); + const workspace = useAtomValue(workspaceAtom); + const writesDisabled = workspace?.settings?.ai?.chatReadOnly === true; + + const inputRef = useRef(null); const handleSuggestionClick = (prompt: string) => { - onSend(prompt, [], []); + inputRef.current?.prefill(prompt); }; return ( @@ -62,6 +72,7 @@ export default function ChatEmptyState({ isStreaming, onSend, onStop }: Props) {

{t("Get started")}

- {SUGGESTIONS.map((s) => ( + {SUGGESTIONS.filter((s) => !writesDisabled || !s.write).map((s) => (