diff --git a/packages/web/public/locales/translation/en.yaml b/packages/web/public/locales/translation/en.yaml index 9ca77c541..56a7af118 100644 --- a/packages/web/public/locales/translation/en.yaml +++ b/packages/web/public/locales/translation/en.yaml @@ -40,6 +40,7 @@ agent_builder: description_placeholder: Describe what your agent does... description_too_long: Description must be 500 characters or less edit_agent: Edit Agent + editor: Editor enable_code_execution: Enabling code execution enter_agent_name: Enter the agent name enter_system_prompt: Enter a system prompt that defines the agent behavior @@ -59,6 +60,9 @@ agent_builder: failed_to_update_agent: Failed to update agent favorites: Favorites filter_by_tag: Filter by tag + generate_short: Generate + generate_with_ai: Generate with AI + generating_prompt: Generating system prompt... loading_agent: Loading agent... mcp_server_configuration: MCP Server Configuration mcp_server_description: >- @@ -78,6 +82,10 @@ agent_builder: no_mcp_servers_match_filter: No MCP servers match your current filter. no_mcp_servers_selected: No MCP servers selected. Your agent will have basic functionality only. no_public_agents_available: No public agents available + overwrite_confirm: Overwrite + overwrite_prompt_message: A system prompt already exists. Do you want to overwrite it with AI-generated prompt? + overwrite_prompt_title: Overwrite System Prompt Confirmation + preview: Preview public: Public Agents public_sharing_description: >- Make this agent available on public agent directories and be discovered and diff --git a/packages/web/public/locales/translation/ja.yaml b/packages/web/public/locales/translation/ja.yaml index ecb8e83bf..69dc2fa4c 100644 --- a/packages/web/public/locales/translation/ja.yaml +++ b/packages/web/public/locales/translation/ja.yaml @@ -41,6 +41,7 @@ agent_builder: description_placeholder: エージェントの機能を説明してください... description_too_long: 説明は500文字以下である必要があります edit_agent: エージェントを編集 + editor: エディター enable_code_execution: コード実行を有効にする enter_agent_name: エージェント名を入力 enter_system_prompt: エージェントの動作を定義するシステムプロンプトを入力 @@ -59,6 +60,9 @@ agent_builder: failed_to_update_agent: エージェントの更新に失敗しました favorites: お気に入り filter_by_tag: タグでフィルター + generate_short: 生成 + generate_with_ai: AIにより生成する + generating_prompt: システムプロンプトを生成中... loading_agent: エージェントを読み込み中... mcp_server_configuration: MCPサーバー設定 mcp_server_description: エージェントに追加機能を提供するMCPサーバーを選択してください。これらのサーバーはセキュリティのため管理者によって事前設定されています。 @@ -76,6 +80,10 @@ agent_builder: no_mcp_servers_match_filter: 現在のフィルターに一致するMCPサーバーがありません。 no_mcp_servers_selected: MCPサーバーが選択されていません。エージェントは基本機能のみ利用できます。 no_public_agents_available: 利用可能な公開エージェントがありません + overwrite_confirm: 上書きする + overwrite_prompt_message: すでにシステムプロンプトが入力されています。AIで生成したプロンプトで上書きしますか? + overwrite_prompt_title: システムプロンプトの上書き確認 + preview: プレビュー public: 公開エージェント public_sharing_description: >- このエージェントを公開し、他のユーザーが発見して利用できるようにします。エージェントはすべてのユーザーに表示されますが、オリジナルを変更することはできません。 diff --git a/packages/web/src/components/agentBuilder/AgentForm.tsx b/packages/web/src/components/agentBuilder/AgentForm.tsx index b834fc127..a7345d967 100644 --- a/packages/web/src/components/agentBuilder/AgentForm.tsx +++ b/packages/web/src/components/agentBuilder/AgentForm.tsx @@ -1,19 +1,24 @@ import React, { useState, useCallback, useEffect } from 'react'; import { useTranslation } from 'react-i18next'; import Button from '../Button'; +import ButtonIcon from '../ButtonIcon'; import InputText from '../InputText'; import Textarea from '../Textarea'; import Select from '../Select'; import MCPServerManager from './MCPServerManager'; +import ModalDialog from '../ModalDialog'; import { MODELS } from '../../hooks/useModel'; import { AgentConfiguration } from 'generative-ai-use-cases'; +import usePromptGeneration from '../../hooks/usePromptGeneration'; +import useMCPServers from '../../hooks/useMCPServers'; +import { PiSparkle, PiStop } from 'react-icons/pi'; export interface AgentFormData { name: string; description: string; systemPrompt: string; modelId: string; - mcpServers: string[]; // Changed to string array + mcpServers: string[]; codeExecutionEnabled: boolean; isPublic: boolean; tags: string[]; @@ -55,6 +60,38 @@ const AgentForm: React.FC = ({ }); const [tagsInput, setTagsInput] = useState(''); + const [showOverwriteDialog, setShowOverwriteDialog] = useState(false); + + // Load available MCP servers using the shared hook + const availableMCPServers = useMCPServers(); + + // Use the prompt generation hook + const { + generatedPrompt, + suggestedMCPServers, + isGenerating, + generate: generatePrompt, + cancel: cancelGeneration, + } = usePromptGeneration({ + modelId: formData.modelId, + agentName: formData.name, + agentDescription: formData.description, + availableMCPServers, + }); + + // Update systemPrompt when generation produces new content + useEffect(() => { + if (generatedPrompt) { + setFormData((prev) => ({ ...prev, systemPrompt: generatedPrompt })); + } + }, [generatedPrompt]); + + // Update MCP servers when AI suggests them + useEffect(() => { + if (suggestedMCPServers.length > 0) { + setFormData((prev) => ({ ...prev, mcpServers: suggestedMCPServers })); + } + }, [suggestedMCPServers]); // Update formData.modelId when availableModels becomes available useEffect(() => { @@ -86,7 +123,6 @@ const AgentForm: React.FC = ({ // Notify parent component when form data changes useEffect(() => { if (onFormDataChange) { - // Parse tags from input for real-time updates const tags = tagsInput .split(',') .map((tag) => tag.trim()) @@ -103,7 +139,6 @@ const AgentForm: React.FC = ({ const handleSave = useCallback(async () => { try { - // Parse tags from input const tags = tagsInput .split(',') .map((tag) => tag.trim()) @@ -115,11 +150,34 @@ const AgentForm: React.FC = ({ }; await onSave(agentData); - } catch (error) { - console.error('Error saving agent:', error); + } catch (err) { + console.error('Error saving agent:', err); } }, [formData, tagsInput, onSave]); + const handleGenerateClick = useCallback(() => { + if (formData.systemPrompt.trim()) { + setShowOverwriteDialog(true); + } else { + setFormData((prev) => ({ ...prev, systemPrompt: '' })); + generatePrompt(); + } + }, [formData.systemPrompt, generatePrompt]); + + const handleConfirmOverwrite = useCallback(() => { + setShowOverwriteDialog(false); + setFormData((prev) => ({ ...prev, systemPrompt: '' })); + generatePrompt(); + }, [generatePrompt]); + + const handleCancelGeneration = useCallback(() => { + cancelGeneration(); + }, [cancelGeneration]); + + // Check if generate button should be disabled + const isGenerateDisabled = + !formData.name.trim() || !formData.description.trim() || loading; + const isFormValid = formData.name && formData.systemPrompt && formData.modelId; @@ -202,10 +260,33 @@ const AgentForm: React.FC = ({ {/* System Prompt */}
- {/* eslint-disable-next-line @shopify/jsx-no-hardcoded-content */} -

- {t('agent_builder.system_prompt')} {'*'} -

+
+ {/* eslint-disable-next-line @shopify/jsx-no-hardcoded-content */} +

+ {t('agent_builder.system_prompt')} {'*'} +

+
+ {isGenerating ? ( + + + + ) : ( + + )} +
+