,
) => void;
leftIcon?: React.ReactNode;
+ edgeRoundness?: string;
};
export type MermaidRendererProps = {
diff --git a/frontend/src/locale/en.json b/frontend/src/locale/en.json
index b8baa70f..a4ec2bde 100644
--- a/frontend/src/locale/en.json
+++ b/frontend/src/locale/en.json
@@ -386,8 +386,20 @@
"promptName": "Prompt Name",
"promptText": "Prompt Text",
"save": "Save",
+ "cancel": "Cancel",
"nameExists": "Name already exists",
- "deleteConfirmation": "Are you sure you want to delete the prompt '{{name}}'?"
+ "deleteConfirmation": "Are you sure you want to delete the prompt '{{name}}'?",
+ "placeholderText": "Type your prompt text here...",
+ "addExamplePlaceholder": "Please summarize this text:",
+ "variablesLabel": "Variables",
+ "variablesSubtext": "Click To Insert Into Prompt",
+ "variablesDescription": "Click to insert into prompt",
+ "systemVariables": "Click to insert into prompt",
+ "toolVariables": "Tool Variables",
+ "learnAboutPrompts": "Learn about Prompts →",
+ "publicPromptEditDisabled": "Public prompts cannot be edited",
+ "promptTypePublic": "public",
+ "promptTypePrivate": "private"
},
"chunk": {
"add": "Add Chunk",
diff --git a/frontend/src/locale/es.json b/frontend/src/locale/es.json
index ff539a2d..8bdc9b32 100644
--- a/frontend/src/locale/es.json
+++ b/frontend/src/locale/es.json
@@ -386,8 +386,20 @@
"promptName": "Nombre del Prompt",
"promptText": "Texto del Prompt",
"save": "Guardar",
+ "cancel": "Cancelar",
"nameExists": "El nombre ya existe",
- "deleteConfirmation": "¿Estás seguro de que deseas eliminar el prompt '{{name}}'?"
+ "deleteConfirmation": "¿Estás seguro de que deseas eliminar el prompt '{{name}}'?",
+ "placeholderText": "Escribe tu texto de prompt aquí...",
+ "addExamplePlaceholder": "Por favor, resume este texto:",
+ "variablesLabel": "Variables",
+ "variablesSubtext": "Haz clic para insertar en el prompt",
+ "variablesDescription": "Haz clic para insertar en el prompt",
+ "systemVariables": "Variables del sistema",
+ "toolVariables": "Variables de herramientas",
+ "learnAboutPrompts": "Aprende sobre los Prompts →",
+ "publicPromptEditDisabled": "Los prompts públicos no se pueden editar",
+ "promptTypePublic": "público",
+ "promptTypePrivate": "privado"
},
"chunk": {
"add": "Agregar Fragmento",
diff --git a/frontend/src/locale/jp.json b/frontend/src/locale/jp.json
index 50a94428..b3f885f7 100644
--- a/frontend/src/locale/jp.json
+++ b/frontend/src/locale/jp.json
@@ -380,14 +380,26 @@
},
"prompts": {
"addPrompt": "プロンプトを追加",
- "addDescription": "カスタムプロンプトを追加してDocsGPTに保存",
+ "addDescription": "カスタムプロンプトを追加して DocsGPT に保存します",
"editPrompt": "プロンプトを編集",
- "editDescription": "カスタムプロンプトを編集してDocsGPTに保存",
+ "editDescription": "カスタムプロンプトを編集して DocsGPT に保存します",
"promptName": "プロンプト名",
- "promptText": "プロンプトテキスト",
+ "promptText": "プロンプトのテキスト",
"save": "保存",
- "nameExists": "名前が既に存在します",
- "deleteConfirmation": "プロンプト「{{name}}」を削除してもよろしいですか?"
+ "cancel": "キャンセル",
+ "nameExists": "この名前はすでに存在します",
+ "deleteConfirmation": "プロンプト『{{name}}』を削除してもよろしいですか?",
+ "placeholderText": "ここにプロンプトのテキストを入力してください…",
+ "addExamplePlaceholder": "このテキストを要約してください:",
+ "variablesLabel": "変数",
+ "variablesSubtext": "クリックしてプロンプトに挿入",
+ "variablesDescription": "クリックしてプロンプトに挿入",
+ "systemVariables": "システム変数",
+ "toolVariables": "ツール変数",
+ "learnAboutPrompts": "プロンプトについて学ぶ →",
+ "publicPromptEditDisabled": "公開プロンプトは編集できません",
+ "promptTypePublic": "公開",
+ "promptTypePrivate": "非公開"
},
"chunk": {
"add": "チャンクを追加",
diff --git a/frontend/src/locale/ru.json b/frontend/src/locale/ru.json
index 18d6ec05..aba8332f 100644
--- a/frontend/src/locale/ru.json
+++ b/frontend/src/locale/ru.json
@@ -379,15 +379,27 @@
"customNamePlaceholder": "Enter custom name (optional)"
},
"prompts": {
- "addPrompt": "Добавить подсказку",
- "addDescription": "Добавить вашу пользовательскую подсказку и сохранить её в DocsGPT",
- "editPrompt": "Редактировать подсказку",
- "editDescription": "Редактировать вашу пользовательскую подсказку и сохранить её в DocsGPT",
- "promptName": "Название подсказки",
- "promptText": "Текст подсказки",
+ "addPrompt": "Добавить промпт",
+ "addDescription": "Добавьте свой собственный промпт и сохраните его в DocsGPT",
+ "editPrompt": "Редактировать промпт",
+ "editDescription": "Отредактируйте свой промпт и сохраните его в DocsGPT",
+ "promptName": "Название промпта",
+ "promptText": "Текст промпта",
"save": "Сохранить",
- "nameExists": "Название уже существует",
- "deleteConfirmation": "Вы уверены, что хотите удалить подсказку «{{name}}»?"
+ "cancel": "Отмена",
+ "nameExists": "Имя уже существует",
+ "deleteConfirmation": "Вы уверены, что хотите удалить промпт «{{name}}»?",
+ "placeholderText": "Введите текст вашего промпта здесь...",
+ "addExamplePlaceholder": "Пожалуйста, кратко изложите этот текст:",
+ "variablesLabel": "Переменные",
+ "variablesSubtext": "Нажмите, чтобы вставить в промпт",
+ "variablesDescription": "Нажмите, чтобы вставить в промпт",
+ "systemVariables": "Системные переменные",
+ "toolVariables": "Переменные инструментов",
+ "learnAboutPrompts": "Узнать о промптах →",
+ "publicPromptEditDisabled": "Публичные промпты нельзя редактировать",
+ "promptTypePublic": "публичный",
+ "promptTypePrivate": "приватный"
},
"chunk": {
"add": "Добавить фрагмент",
diff --git a/frontend/src/locale/zh-TW.json b/frontend/src/locale/zh-TW.json
index f84cc65a..64f24074 100644
--- a/frontend/src/locale/zh-TW.json
+++ b/frontend/src/locale/zh-TW.json
@@ -386,8 +386,20 @@
"promptName": "提示名稱",
"promptText": "提示文字",
"save": "儲存",
+ "cancel": "取消",
"nameExists": "名稱已存在",
- "deleteConfirmation": "您確定要刪除提示「{{name}}」嗎?"
+ "deleteConfirmation": "您確定要刪除提示「{{name}}」嗎?",
+ "placeholderText": "在此輸入提示內容...",
+ "addExamplePlaceholder": "請總結此文本:",
+ "variablesLabel": "變數",
+ "variablesSubtext": "點擊以插入提示中",
+ "variablesDescription": "點擊以插入到提示中",
+ "systemVariables": "點擊以插入提示中",
+ "toolVariables": "工具變數",
+ "learnAboutPrompts": "了解提示 →",
+ "publicPromptEditDisabled": "公共提示無法編輯",
+ "promptTypePublic": "公共",
+ "promptTypePrivate": "私人"
},
"chunk": {
"add": "新增區塊",
diff --git a/frontend/src/locale/zh.json b/frontend/src/locale/zh.json
index 7b8e5bbf..d1eeb144 100644
--- a/frontend/src/locale/zh.json
+++ b/frontend/src/locale/zh.json
@@ -387,7 +387,19 @@
"promptText": "提示文本",
"save": "保存",
"nameExists": "名称已存在",
- "deleteConfirmation": "您确定要删除提示'{{name}}'吗?"
+ "deleteConfirmation": "您确定要删除提示'{{name}}'吗?",
+ "cancel": "取消",
+ "placeholderText": "在此輸入提示內容...",
+ "addExamplePlaceholder": "請總結此文本:",
+ "variablesLabel": "變數",
+ "variablesSubtext": "點擊以插入提示中",
+ "variablesDescription": "點擊以插入到提示中",
+ "systemVariables": "點擊以插入提示中",
+ "toolVariables": "工具變數",
+ "learnAboutPrompts": "了解提示 →",
+ "publicPromptEditDisabled": "公共提示無法編輯",
+ "promptTypePublic": "公共",
+ "promptTypePrivate": "私人"
},
"chunk": {
"add": "添加块",
diff --git a/frontend/src/preferences/PromptsModal.tsx b/frontend/src/preferences/PromptsModal.tsx
index 42113475..72193852 100644
--- a/frontend/src/preferences/PromptsModal.tsx
+++ b/frontend/src/preferences/PromptsModal.tsx
@@ -1,8 +1,77 @@
import { ActiveState } from '../models/misc';
import Input from '../components/Input';
+import { Link } from 'react-router-dom';
+
import React from 'react';
import { useTranslation } from 'react-i18next';
+import { useSelector } from 'react-redux';
import WrapperModal from '../modals/WrapperModal';
+import Dropdown from '../components/Dropdown';
+import BookIcon from '../assets/book.svg';
+import userService from '../api/services/userService';
+import { selectToken } from '../preferences/preferenceSlice';
+import { UserToolType } from '../settings/types';
+
+// Custom hook for fetching tool variables
+const useToolVariables = () => {
+ const token = useSelector(selectToken);
+ const [toolVariables, setToolVariables] = React.useState<
+ { label: string; value: string }[]
+ >([]);
+
+ React.useEffect(() => {
+ const fetchToolVariables = async () => {
+ try {
+ const response = await userService.getUserTools(token);
+ const data = await response.json();
+
+ if (data.success && data.tools) {
+ const filteredActions: { label: string; value: string }[] = [];
+
+ data.tools.forEach((tool: UserToolType) => {
+ if (tool.actions && tool.status) {
+ // Only include active tools
+ tool.actions.forEach((action: any) => {
+ if (action.active) {
+ const canUseAction =
+ !action.parameters?.properties ||
+ Object.entries(action.parameters.properties).every(
+ ([paramName, param]: [string, any]) => {
+ // Parameter is usable if:
+ // 1. It's filled by LLM (true) OR
+ // 2. It has a value in the tool config
+ return (
+ param.filled_by_llm === true ||
+ (tool.config &&
+ tool.config[paramName] &&
+ tool.config[paramName] !== '')
+ );
+ },
+ );
+
+ if (canUseAction) {
+ filteredActions.push({
+ label: `${action.name} (${tool.displayName || tool.name})`,
+ value: `tools.${tool.name}.${action.name}`,
+ });
+ }
+ }
+ });
+ }
+ });
+
+ setToolVariables(filteredActions);
+ }
+ } catch (error) {
+ console.error('Error fetching tool variables:', error);
+ }
+ };
+
+ fetchToolVariables();
+ }, [token]);
+
+ return toolVariables;
+};
function AddPrompt({
setModalState,
@@ -22,52 +91,188 @@ function AddPrompt({
disableSave: boolean;
}) {
const { t } = useTranslation();
+ const toolVariables = useToolVariables();
return (
-
+
{t('modals.prompts.addPrompt')}
-
+
{t('modals.prompts.addDescription')}
setNewPromptName(e.target.value)}
labelBgClassName="bg-white dark:bg-[#26272E]"
- borderVariant="thin"
+ borderVariant="thick"
/>
-
-
+
+
+
-
-
-
-
+
+
+
+
+ {t('modals.prompts.variablesLabel')}
+
+
+ {t('modals.prompts.variablesDescription')}
+
+
+
+
+ {
+ const textarea = document.getElementById(
+ 'new-prompt-content',
+ ) as HTMLTextAreaElement;
+ if (textarea) {
+ const cursorPosition = textarea.selectionStart;
+ const textBefore = newPromptContent.slice(0, cursorPosition);
+ const textAfter = newPromptContent.slice(cursorPosition);
+
+ // Add leading space if needed
+ const needsSpace =
+ cursorPosition > 0 &&
+ newPromptContent.charAt(cursorPosition - 1) !== ' ';
+
+ const newText =
+ textBefore +
+ (needsSpace ? ' ' : '') +
+ `{${option.value}}` +
+ textAfter;
+ setNewPromptContent(newText);
+
+ setTimeout(() => {
+ textarea.focus();
+ textarea.setSelectionRange(
+ cursorPosition +
+ option.value.length +
+ 2 +
+ (needsSpace ? 1 : 0),
+ cursorPosition +
+ option.value.length +
+ 2 +
+ (needsSpace ? 1 : 0),
+ );
+ }, 0);
+ }
+ }}
+ placeholder="System Variables"
+ size="w-[140px] sm:w-[185px]"
+ rounded="3xl"
+ border="border"
+ contentSize="text-[12px] sm:text-[14px]"
+ />
+
+ {
+ const textarea = document.getElementById(
+ 'new-prompt-content',
+ ) as HTMLTextAreaElement;
+ if (textarea) {
+ const cursorPosition = textarea.selectionStart;
+ const textBefore = newPromptContent.slice(0, cursorPosition);
+ const textAfter = newPromptContent.slice(cursorPosition);
+
+ // Add leading space if needed
+ const needsSpace =
+ cursorPosition > 0 &&
+ newPromptContent.charAt(cursorPosition - 1) !== ' ';
+
+ const newText =
+ textBefore +
+ (needsSpace ? ' ' : '') +
+ `{{ ${option.value} }}` +
+ textAfter;
+ setNewPromptContent(newText);
+ setTimeout(() => {
+ textarea.focus();
+ textarea.setSelectionRange(
+ cursorPosition +
+ option.value.length +
+ 6 +
+ (needsSpace ? 1 : 0),
+ cursorPosition +
+ option.value.length +
+ 6 +
+ (needsSpace ? 1 : 0),
+ );
+ }, 0);
+ }
+ }}
+ placeholder="Tool Variables"
+ size="w-[140px] sm:w-[171px]"
+ rounded="3xl"
+ border="border"
+ contentSize="text-[12px] sm:text-[14px]"
+ />
+
+
+
+
+
+

+
+ {t('modals.prompts.learnAboutPrompts')}
+
+
+
+
+
+
+
+
+
);
@@ -93,54 +298,191 @@ function EditPrompt({
disableSave: boolean;
}) {
const { t } = useTranslation();
+ const toolVariables = useToolVariables();
return (
-
-
- {t('modals.prompts.editPrompt')}
-
-
- {t('modals.prompts.editDescription')}
-
-
-
setEditPromptName(e.target.value)}
- labelBgClassName="bg-white dark:bg-charleston-green-2"
- borderVariant="thin"
- />
-
-
- {t('modals.prompts.promptText')}
-
-
-
+
+ {t('modals.prompts.editPrompt')}
+
+
+ {t('modals.prompts.editDescription')}
+
+
+
setEditPromptName(e.target.value)}
+ labelBgClassName="bg-white dark:bg-[#26272E]"
+ borderVariant="thick"
+ />
+
+
+ />
+
-
+
+
+
+
+
+ {t('modals.prompts.variablesLabel')}
+
+
+ {t('modals.prompts.variablesDescription')}
+
+
+
+
+ {
+ const textarea = document.getElementById(
+ 'edit-prompt-content',
+ ) as HTMLTextAreaElement;
+ if (textarea) {
+ const cursorPosition = textarea.selectionStart;
+ const textBefore = editPromptContent.slice(0, cursorPosition);
+ const textAfter = editPromptContent.slice(cursorPosition);
+
+ // Add leading space if needed
+ const needsSpace =
+ cursorPosition > 0 &&
+ editPromptContent.charAt(cursorPosition - 1) !== ' ';
+
+ const newText =
+ textBefore +
+ (needsSpace ? ' ' : '') +
+ `{${option.value}}` +
+ textAfter;
+ setEditPromptContent(newText);
+
+ setTimeout(() => {
+ textarea.focus();
+ textarea.setSelectionRange(
+ cursorPosition +
+ option.value.length +
+ 2 +
+ (needsSpace ? 1 : 0),
+ cursorPosition +
+ option.value.length +
+ 2 +
+ (needsSpace ? 1 : 0),
+ );
+ }, 0);
+ }
+ }}
+ placeholder="System Variables"
+ size="w-[140px] sm:w-[185px]"
+ rounded="3xl"
+ border="border"
+ contentSize="text-[12px] sm:text-[14px]"
+ />
+
+ {
+ const textarea = document.getElementById(
+ 'edit-prompt-content',
+ ) as HTMLTextAreaElement;
+ if (textarea) {
+ const cursorPosition = textarea.selectionStart;
+ const textBefore = editPromptContent.slice(0, cursorPosition);
+ const textAfter = editPromptContent.slice(cursorPosition);
+
+ // Add leading space if needed
+ const needsSpace =
+ cursorPosition > 0 &&
+ editPromptContent.charAt(cursorPosition - 1) !== ' ';
+
+ const newText =
+ textBefore +
+ (needsSpace ? ' ' : '') +
+ `{{ ${option.value} }}` +
+ textAfter;
+ setEditPromptContent(newText);
+ setTimeout(() => {
+ textarea.focus();
+ textarea.setSelectionRange(
+ cursorPosition +
+ option.value.length +
+ 6 +
+ (needsSpace ? 1 : 0),
+ cursorPosition +
+ option.value.length +
+ 6 +
+ (needsSpace ? 1 : 0),
+ );
+ }, 0);
+ }
+ }}
+ placeholder="Tool Variables"
+ size="w-[140px] sm:w-[171px]"
+ rounded="3xl"
+ border="border"
+ contentSize="text-[12px] sm:text-[14px]"
+ />
+
+
+
+
+
+

+
+ {t('modals.prompts.learnAboutPrompts')}
+
+
+
+
+
+
+