From 1b4b92ced20ffc7f99b0aa3b5dd4d544e4b87295 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Mar 2026 13:25:04 +0000 Subject: [PATCH 1/6] Initial plan From a736ca0fc0b7b2184165bda00d2899dac9063814 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 1 Mar 2026 13:41:03 +0000 Subject: [PATCH 2/6] Add AI prompt execution command (aiPrompt mode) Co-authored-by: ujiro99 <677231+ujiro99@users.noreply.github.com> --- .../public/_locales/de/messages.json | 27 ++++ .../public/_locales/en/messages.json | 27 ++++ .../public/_locales/es/messages.json | 27 ++++ .../public/_locales/fr/messages.json | 27 ++++ .../public/_locales/hi/messages.json | 27 ++++ .../public/_locales/id/messages.json | 27 ++++ .../public/_locales/it/messages.json | 27 ++++ .../public/_locales/ja/messages.json | 27 ++++ .../public/_locales/ko/messages.json | 27 ++++ .../public/_locales/ms/messages.json | 27 ++++ .../public/_locales/pt_BR/messages.json | 27 ++++ .../public/_locales/pt_PT/messages.json | 27 ++++ .../public/_locales/ru/messages.json | 27 ++++ .../public/_locales/zh_CN/messages.json | 27 ++++ packages/extension/src/action/aiPrompt.ts | 121 ++++++++++++++++++ packages/extension/src/action/index.ts | 2 + .../option/editor/AiPromptSection.tsx | 99 ++++++++++++++ .../option/editor/CommandEditDialog.tsx | 24 +++- .../components/option/editor/CommandType.tsx | 2 + packages/extension/src/const.ts | 11 +- packages/extension/src/services/aiPrompt.ts | 82 ++++++++++++ packages/extension/src/types/index.ts | 11 ++ packages/extension/src/types/schema.ts | 38 ++++++ packages/shared/src/constants/open-mode.ts | 1 + 24 files changed, 767 insertions(+), 2 deletions(-) create mode 100644 packages/extension/src/action/aiPrompt.ts create mode 100644 packages/extension/src/components/option/editor/AiPromptSection.tsx create mode 100644 packages/extension/src/services/aiPrompt.ts diff --git a/packages/extension/public/_locales/de/messages.json b/packages/extension/public/_locales/de/messages.json index 2cb260fe..f715b75e 100644 --- a/packages/extension/public/_locales/de/messages.json +++ b/packages/extension/public/_locales/de/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "Seitenaktion" }, + "Option_openMode_aiPrompt": { + "message": "KI-Prompt" + }, + "Option_openMode_aiPrompt_desc": { + "message": "Führt einen vordefinierten Prompt auf einem KI-Dienst aus" + }, "Option_commandType_title": { "message": "Befehlstyp wählen" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "Webseiten-Operationen aufzeichnen und wiedergeben" }, + "Option_commandType_aiPrompt_title": { + "message": "KI-Prompt" + }, + "Option_commandType_aiPrompt_desc": { + "message": "Führt einen vordefinierten Prompt auf einem KI-Dienst aus" + }, "Option_commandType_copy_title": { "message": "Text kopieren" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "Verzögerungszeit" }, + "Option_aiPrompt_service": { + "message": "KI-Dienst" + }, + "Option_aiPrompt_service_desc": { + "message": "Wählen Sie den zu verwendenden KI-Dienst aus" + }, + "Option_aiPrompt_prompt": { + "message": "Prompt" + }, + "Option_aiPrompt_prompt_desc": { + "message": "Prompt-Vorlage. Verwenden Sie das Einfügemenü, um Variablen hinzuzufügen (ausgewählter Text, URL, Zwischenablage)." + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "Prompt hier eingeben..." + }, "Option_userVariables": { "message": "Benutzervariablen" }, diff --git a/packages/extension/public/_locales/en/messages.json b/packages/extension/public/_locales/en/messages.json index 2a6a37fd..6dce45d2 100644 --- a/packages/extension/public/_locales/en/messages.json +++ b/packages/extension/public/_locales/en/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "Page Action" }, + "Option_openMode_aiPrompt": { + "message": "AI Prompt" + }, + "Option_openMode_aiPrompt_desc": { + "message": "Run a predefined prompt on an AI service" + }, "Option_commandType_title": { "message": "Select Command Type" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "Record and replay web page operations" }, + "Option_commandType_aiPrompt_title": { + "message": "AI Prompt" + }, + "Option_commandType_aiPrompt_desc": { + "message": "Run a predefined prompt on an AI service" + }, "Option_commandType_copy_title": { "message": "Copy Text" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "Delay time" }, + "Option_aiPrompt_service": { + "message": "AI Service" + }, + "Option_aiPrompt_service_desc": { + "message": "Select the AI service to use" + }, + "Option_aiPrompt_prompt": { + "message": "Prompt" + }, + "Option_aiPrompt_prompt_desc": { + "message": "Prompt template. Use the insert menu to add variables (selected text, URL, clipboard)." + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "Enter your prompt here..." + }, "Option_userVariables": { "message": "User Variables" }, diff --git a/packages/extension/public/_locales/es/messages.json b/packages/extension/public/_locales/es/messages.json index 7ddb0d23..c17bb895 100644 --- a/packages/extension/public/_locales/es/messages.json +++ b/packages/extension/public/_locales/es/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "Acción de Página" }, + "Option_openMode_aiPrompt": { + "message": "Prompt IA" + }, + "Option_openMode_aiPrompt_desc": { + "message": "Ejecuta un prompt predefinido en un servicio de IA" + }, "Option_commandType_title": { "message": "Seleccionar Tipo de Comando" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "Grabar y reproducir operaciones de páginas web" }, + "Option_commandType_aiPrompt_title": { + "message": "Prompt IA" + }, + "Option_commandType_aiPrompt_desc": { + "message": "Ejecuta un prompt predefinido en un servicio de IA" + }, "Option_commandType_copy_title": { "message": "Copiar Texto" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "Tiempo de retraso" }, + "Option_aiPrompt_service": { + "message": "Servicio IA" + }, + "Option_aiPrompt_service_desc": { + "message": "Selecciona el servicio de IA a utilizar" + }, + "Option_aiPrompt_prompt": { + "message": "Prompt" + }, + "Option_aiPrompt_prompt_desc": { + "message": "Plantilla de prompt. Usa el menú de inserción para agregar variables (texto seleccionado, URL, portapapeles)." + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "Ingresa tu prompt aquí..." + }, "Option_userVariables": { "message": "Variables de Usuario" }, diff --git a/packages/extension/public/_locales/fr/messages.json b/packages/extension/public/_locales/fr/messages.json index f2f29ed6..a254254d 100644 --- a/packages/extension/public/_locales/fr/messages.json +++ b/packages/extension/public/_locales/fr/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "Action de Page" }, + "Option_openMode_aiPrompt": { + "message": "Prompt IA" + }, + "Option_openMode_aiPrompt_desc": { + "message": "Exécute un prompt prédéfini sur un service IA" + }, "Option_commandType_title": { "message": "Sélectionner le Type de Commande" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "Enregistrer et reproduire les opérations de pages web" }, + "Option_commandType_aiPrompt_title": { + "message": "Prompt IA" + }, + "Option_commandType_aiPrompt_desc": { + "message": "Exécute un prompt prédéfini sur un service IA" + }, "Option_commandType_copy_title": { "message": "Copier le Texte" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "Temps de délai" }, + "Option_aiPrompt_service": { + "message": "Service IA" + }, + "Option_aiPrompt_service_desc": { + "message": "Sélectionner le service IA à utiliser" + }, + "Option_aiPrompt_prompt": { + "message": "Prompt" + }, + "Option_aiPrompt_prompt_desc": { + "message": "Modèle de prompt. Utilisez le menu d'insertion pour ajouter des variables (texte sélectionné, URL, presse-papiers)." + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "Saisissez votre prompt ici..." + }, "Option_userVariables": { "message": "Variables Utilisateur" }, diff --git a/packages/extension/public/_locales/hi/messages.json b/packages/extension/public/_locales/hi/messages.json index 700f4f31..c0eabbea 100644 --- a/packages/extension/public/_locales/hi/messages.json +++ b/packages/extension/public/_locales/hi/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "पेज एक्शन" }, + "Option_openMode_aiPrompt": { + "message": "AI प्रॉम्प्ट" + }, + "Option_openMode_aiPrompt_desc": { + "message": "AI सेवा पर पूर्व-निर्धारित प्रॉम्प्ट चलाएं" + }, "Option_commandType_title": { "message": "कमांड प्रकार चुनें" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "वेब पेज ऑपरेशन रिकॉर्ड और रीप्ले करें" }, + "Option_commandType_aiPrompt_title": { + "message": "AI प्रॉम्प्ट" + }, + "Option_commandType_aiPrompt_desc": { + "message": "AI सेवा पर पूर्व-निर्धारित प्रॉम्प्ट चलाएं" + }, "Option_commandType_copy_title": { "message": "टेक्स्ट कॉपी करें" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "प्रतीक्षा समय" }, + "Option_aiPrompt_service": { + "message": "AI सेवा" + }, + "Option_aiPrompt_service_desc": { + "message": "उपयोग करने के लिए AI सेवा चुनें" + }, + "Option_aiPrompt_prompt": { + "message": "प्रॉम्प्ट" + }, + "Option_aiPrompt_prompt_desc": { + "message": "प्रॉम्प्ट टेम्पलेट। वेरिएबल जोड़ने के लिए इन्सर्ट मेनू का उपयोग करें (चुना गया टेक्स्ट, URL, क्लिपबोर्ड)।" + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "यहाँ अपना प्रॉम्प्ट दर्ज करें..." + }, "Option_userVariables": { "message": "उपयोगकर्ता चर" }, diff --git a/packages/extension/public/_locales/id/messages.json b/packages/extension/public/_locales/id/messages.json index b1d44abc..e0c31275 100644 --- a/packages/extension/public/_locales/id/messages.json +++ b/packages/extension/public/_locales/id/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "Tindakan Halaman" }, + "Option_openMode_aiPrompt": { + "message": "Prompt AI" + }, + "Option_openMode_aiPrompt_desc": { + "message": "Jalankan prompt yang telah ditentukan pada layanan AI" + }, "Option_commandType_title": { "message": "Pilih Jenis Perintah" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "Rekam dan putar operasi halaman web" }, + "Option_commandType_aiPrompt_title": { + "message": "Prompt AI" + }, + "Option_commandType_aiPrompt_desc": { + "message": "Jalankan prompt yang telah ditentukan pada layanan AI" + }, "Option_commandType_copy_title": { "message": "Salin Teks" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "Waktu tunda" }, + "Option_aiPrompt_service": { + "message": "Layanan AI" + }, + "Option_aiPrompt_service_desc": { + "message": "Pilih layanan AI yang akan digunakan" + }, + "Option_aiPrompt_prompt": { + "message": "Prompt" + }, + "Option_aiPrompt_prompt_desc": { + "message": "Template prompt. Gunakan menu sisipan untuk menambahkan variabel (teks pilihan, URL, clipboard)." + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "Masukkan prompt Anda di sini..." + }, "Option_userVariables": { "message": "Variabel Pengguna" }, diff --git a/packages/extension/public/_locales/it/messages.json b/packages/extension/public/_locales/it/messages.json index 7381941f..c60cb50c 100644 --- a/packages/extension/public/_locales/it/messages.json +++ b/packages/extension/public/_locales/it/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "Azione pagina" }, + "Option_openMode_aiPrompt": { + "message": "Prompt AI" + }, + "Option_openMode_aiPrompt_desc": { + "message": "Esegui un prompt predefinito su un servizio AI" + }, "Option_commandType_title": { "message": "Seleziona Tipo di Comando" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "Registra e riproduci operazioni delle pagine web" }, + "Option_commandType_aiPrompt_title": { + "message": "Prompt AI" + }, + "Option_commandType_aiPrompt_desc": { + "message": "Esegui un prompt predefinito su un servizio AI" + }, "Option_commandType_copy_title": { "message": "Copia Testo" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "Tempo di attesa" }, + "Option_aiPrompt_service": { + "message": "Servizio AI" + }, + "Option_aiPrompt_service_desc": { + "message": "Seleziona il servizio AI da utilizzare" + }, + "Option_aiPrompt_prompt": { + "message": "Prompt" + }, + "Option_aiPrompt_prompt_desc": { + "message": "Modello prompt. Usa il menu di inserimento per aggiungere variabili (testo selezionato, URL, appunti)." + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "Inserisci il tuo prompt qui..." + }, "Option_userVariables": { "message": "Variabili Utente" }, diff --git a/packages/extension/public/_locales/ja/messages.json b/packages/extension/public/_locales/ja/messages.json index 4d8fcad8..ae860458 100644 --- a/packages/extension/public/_locales/ja/messages.json +++ b/packages/extension/public/_locales/ja/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "ページアクション" }, + "Option_openMode_aiPrompt": { + "message": "AIプロンプト" + }, + "Option_openMode_aiPrompt_desc": { + "message": "AIサービスで定義済みのプロンプトを実行します" + }, "Option_commandType_title": { "message": "コマンドの種類を選ぶ" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "Webページ上の操作を記録・再生します" }, + "Option_commandType_aiPrompt_title": { + "message": "AIプロンプト" + }, + "Option_commandType_aiPrompt_desc": { + "message": "AIサービスで定義済みのプロンプトを実行します" + }, "Option_commandType_copy_title": { "message": "テキストコピー" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "遅延時間" }, + "Option_aiPrompt_service": { + "message": "AIサービス" + }, + "Option_aiPrompt_service_desc": { + "message": "使用するAIサービスを選択してください" + }, + "Option_aiPrompt_prompt": { + "message": "プロンプト" + }, + "Option_aiPrompt_prompt_desc": { + "message": "プロンプトのテンプレート。挿入メニューで変数(選択テキスト、URL、クリップボード)を追加できます。" + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "プロンプトをここに入力..." + }, "Option_userVariables": { "message": "ユーザー変数" }, diff --git a/packages/extension/public/_locales/ko/messages.json b/packages/extension/public/_locales/ko/messages.json index e2cfa418..9907c1e1 100644 --- a/packages/extension/public/_locales/ko/messages.json +++ b/packages/extension/public/_locales/ko/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "페이지 작업" }, + "Option_openMode_aiPrompt": { + "message": "AI 프롬프트" + }, + "Option_openMode_aiPrompt_desc": { + "message": "AI 서비스에서 미리 정의된 프롬프트를 실행합니다" + }, "Option_commandType_title": { "message": "명령 유형 선택" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "웹 페이지 작업을 기록하고 재생합니다" }, + "Option_commandType_aiPrompt_title": { + "message": "AI 프롬프트" + }, + "Option_commandType_aiPrompt_desc": { + "message": "AI 서비스에서 미리 정의된 프롬프트를 실행합니다" + }, "Option_commandType_copy_title": { "message": "텍스트 복사" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "지연 시간" }, + "Option_aiPrompt_service": { + "message": "AI 서비스" + }, + "Option_aiPrompt_service_desc": { + "message": "사용할 AI 서비스를 선택하세요" + }, + "Option_aiPrompt_prompt": { + "message": "프롬프트" + }, + "Option_aiPrompt_prompt_desc": { + "message": "프롬프트 템플릿. 삽입 메뉴를 사용하여 변수(선택된 텍스트, URL, 클립보드)를 추가하세요." + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "여기에 프롬프트를 입력하세요..." + }, "Option_userVariables": { "message": "사용자 변수" }, diff --git a/packages/extension/public/_locales/ms/messages.json b/packages/extension/public/_locales/ms/messages.json index 7bbbbbb9..12fbe5dd 100644 --- a/packages/extension/public/_locales/ms/messages.json +++ b/packages/extension/public/_locales/ms/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "Tindakan Halaman" }, + "Option_openMode_aiPrompt": { + "message": "Prompt AI" + }, + "Option_openMode_aiPrompt_desc": { + "message": "Jalankan prompt yang telah ditetapkan pada perkhidmatan AI" + }, "Option_commandType_title": { "message": "Pilih Jenis Arahan" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "Rakam dan mainkan operasi halaman web" }, + "Option_commandType_aiPrompt_title": { + "message": "Prompt AI" + }, + "Option_commandType_aiPrompt_desc": { + "message": "Jalankan prompt yang telah ditetapkan pada perkhidmatan AI" + }, "Option_commandType_copy_title": { "message": "Salin Teks" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "Masa kelewatan" }, + "Option_aiPrompt_service": { + "message": "Perkhidmatan AI" + }, + "Option_aiPrompt_service_desc": { + "message": "Pilih perkhidmatan AI yang hendak digunakan" + }, + "Option_aiPrompt_prompt": { + "message": "Prompt" + }, + "Option_aiPrompt_prompt_desc": { + "message": "Templat prompt. Gunakan menu sisipan untuk menambah pemboleh ubah (teks dipilih, URL, papan klip)." + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "Masukkan prompt anda di sini..." + }, "Option_userVariables": { "message": "Pembolehubah Pengguna" }, diff --git a/packages/extension/public/_locales/pt_BR/messages.json b/packages/extension/public/_locales/pt_BR/messages.json index f1682e77..e7cd10d5 100644 --- a/packages/extension/public/_locales/pt_BR/messages.json +++ b/packages/extension/public/_locales/pt_BR/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "Ação de Página" }, + "Option_openMode_aiPrompt": { + "message": "Prompt de IA" + }, + "Option_openMode_aiPrompt_desc": { + "message": "Execute um prompt predefinido em um serviço de IA" + }, "Option_commandType_title": { "message": "Selecionar Tipo de Comando" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "Gravar e reproduzir operações de páginas web" }, + "Option_commandType_aiPrompt_title": { + "message": "Prompt de IA" + }, + "Option_commandType_aiPrompt_desc": { + "message": "Execute um prompt predefinido em um serviço de IA" + }, "Option_commandType_copy_title": { "message": "Copiar Texto" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "Tempo de atraso" }, + "Option_aiPrompt_service": { + "message": "Serviço de IA" + }, + "Option_aiPrompt_service_desc": { + "message": "Selecione o serviço de IA a ser usado" + }, + "Option_aiPrompt_prompt": { + "message": "Prompt" + }, + "Option_aiPrompt_prompt_desc": { + "message": "Modelo de prompt. Use o menu de inserção para adicionar variáveis (texto selecionado, URL, área de transferência)." + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "Digite seu prompt aqui..." + }, "Option_userVariables": { "message": "Variáveis do Usuário" }, diff --git a/packages/extension/public/_locales/pt_PT/messages.json b/packages/extension/public/_locales/pt_PT/messages.json index f4f49e35..05f4bd73 100644 --- a/packages/extension/public/_locales/pt_PT/messages.json +++ b/packages/extension/public/_locales/pt_PT/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "Ação de Página" }, + "Option_openMode_aiPrompt": { + "message": "Prompt de IA" + }, + "Option_openMode_aiPrompt_desc": { + "message": "Execute um prompt predefinido num serviço de IA" + }, "Option_commandType_title": { "message": "Selecionar Tipo de Comando" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "Gravar e reproduzir operações de páginas web" }, + "Option_commandType_aiPrompt_title": { + "message": "Prompt de IA" + }, + "Option_commandType_aiPrompt_desc": { + "message": "Execute um prompt predefinido num serviço de IA" + }, "Option_commandType_copy_title": { "message": "Copiar Texto" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "Tempo de atraso" }, + "Option_aiPrompt_service": { + "message": "Serviço de IA" + }, + "Option_aiPrompt_service_desc": { + "message": "Selecione o serviço de IA a utilizar" + }, + "Option_aiPrompt_prompt": { + "message": "Prompt" + }, + "Option_aiPrompt_prompt_desc": { + "message": "Modelo de prompt. Use o menu de inserção para adicionar variáveis (texto selecionado, URL, área de transferência)." + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "Introduza o seu prompt aqui..." + }, "Option_userVariables": { "message": "Variáveis do Utilizador" }, diff --git a/packages/extension/public/_locales/ru/messages.json b/packages/extension/public/_locales/ru/messages.json index 039ec78e..aaa98d5d 100644 --- a/packages/extension/public/_locales/ru/messages.json +++ b/packages/extension/public/_locales/ru/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "Действие страницы" }, + "Option_openMode_aiPrompt": { + "message": "AI-промпт" + }, + "Option_openMode_aiPrompt_desc": { + "message": "Запускает предопределённый промпт в сервисе ИИ" + }, "Option_commandType_title": { "message": "Выбрать тип команды" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "Записывать и воспроизводить операции веб-страниц" }, + "Option_commandType_aiPrompt_title": { + "message": "AI-промпт" + }, + "Option_commandType_aiPrompt_desc": { + "message": "Запускает предопределённый промпт в сервисе ИИ" + }, "Option_commandType_copy_title": { "message": "Копировать текст" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "Время ожидания" }, + "Option_aiPrompt_service": { + "message": "Сервис ИИ" + }, + "Option_aiPrompt_service_desc": { + "message": "Выберите сервис ИИ для использования" + }, + "Option_aiPrompt_prompt": { + "message": "Промпт" + }, + "Option_aiPrompt_prompt_desc": { + "message": "Шаблон промпта. Используйте меню вставки для добавления переменных (выбранный текст, URL, буфер обмена)." + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "Введите ваш промпт здесь..." + }, "Option_userVariables": { "message": "Пользовательские Переменные" }, diff --git a/packages/extension/public/_locales/zh_CN/messages.json b/packages/extension/public/_locales/zh_CN/messages.json index 9a43837c..8b761267 100644 --- a/packages/extension/public/_locales/zh_CN/messages.json +++ b/packages/extension/public/_locales/zh_CN/messages.json @@ -308,6 +308,12 @@ "Option_openMode_pageAction": { "message": "页面操作" }, + "Option_openMode_aiPrompt": { + "message": "AI提示词" + }, + "Option_openMode_aiPrompt_desc": { + "message": "在AI服务上运行预定义的提示词" + }, "Option_commandType_title": { "message": "选择命令类型" }, @@ -326,6 +332,12 @@ "Option_commandType_pageAction_desc": { "message": "录制和重放网页操作" }, + "Option_commandType_aiPrompt_title": { + "message": "AI提示词" + }, + "Option_commandType_aiPrompt_desc": { + "message": "在AI服务上运行预定义的提示词" + }, "Option_commandType_copy_title": { "message": "复制文本" }, @@ -425,6 +437,21 @@ "Option_pageAction_delay": { "message": "等待时间" }, + "Option_aiPrompt_service": { + "message": "AI服务" + }, + "Option_aiPrompt_service_desc": { + "message": "选择要使用的AI服务" + }, + "Option_aiPrompt_prompt": { + "message": "提示词" + }, + "Option_aiPrompt_prompt_desc": { + "message": "提示词模板。使用插入菜单添加变量(选中文本、URL、剪贴板)。" + }, + "Option_aiPrompt_prompt_placeholder": { + "message": "在此输入您的提示词..." + }, "Option_userVariables": { "message": "用户变量" }, diff --git a/packages/extension/src/action/aiPrompt.ts b/packages/extension/src/action/aiPrompt.ts new file mode 100644 index 00000000..5050eaaf --- /dev/null +++ b/packages/extension/src/action/aiPrompt.ts @@ -0,0 +1,121 @@ +import { Ipc, BgCommand } from "@/services/ipc" +import { getScreenSize, getWindowPosition } from "@/services/screen" +import { isValidString, generateRandomID } from "@/lib/utils" +import { PAGE_ACTION_OPEN_MODE, PAGE_ACTION_CONTROL, PAGE_ACTION_EVENT, SelectorType } from "@/const" +import { PopupOption } from "@/services/option/defaultSettings" +import type { ExecuteCommandParams, PageActionStep } from "@/types" +import type { OpenAndRunProps } from "@/services/pageAction/background" +import { findAiService } from "@/services/aiPrompt" + +const isAiPromptCommand = (command: any): boolean => { + return command.openMode === "aiPrompt" && command.aiPromptOption != null +} + +export const AiPrompt = { + async execute({ + selectionText, + command, + position, + useSecondary, + }: ExecuteCommandParams) { + if (!isAiPromptCommand(command)) { + console.error("command is not for AiPrompt.") + return + } + + const aiPromptOption = (command as any).aiPromptOption + const service = findAiService(aiPromptOption.serviceId) + + if (!service) { + console.error(`AI service not found: ${aiPromptOption.serviceId}`) + return + } + + if (!isValidString(service.url)) { + console.error("AI service URL is not valid.") + return + } + + if (position === null) { + console.error("position is null.") + return + } + + const openMode = useSecondary + ? aiPromptOption.openMode === PAGE_ACTION_OPEN_MODE.TAB + ? PAGE_ACTION_OPEN_MODE.WINDOW + : aiPromptOption.openMode === PAGE_ACTION_OPEN_MODE.WINDOW + ? PAGE_ACTION_OPEN_MODE.TAB + : PAGE_ACTION_OPEN_MODE.TAB + : aiPromptOption.openMode + + // Build dynamic page action steps for the AI service + const inputSelector = service.inputSelectors[0] + const submitSelector = service.submitSelectors[0] + + const steps: PageActionStep[] = [ + { + id: generateRandomID(), + delayMs: 0, + skipRenderWait: false, + param: { + type: PAGE_ACTION_CONTROL.start, + label: "Start", + }, + }, + { + id: generateRandomID(), + delayMs: 500, + skipRenderWait: false, + param: { + type: PAGE_ACTION_EVENT.input, + label: "Input prompt", + selector: inputSelector, + selectorType: SelectorType.css, + value: aiPromptOption.prompt, + }, + }, + { + id: generateRandomID(), + delayMs: 200, + skipRenderWait: false, + param: { + type: PAGE_ACTION_EVENT.click, + label: "Submit", + selector: submitSelector, + selectorType: SelectorType.css, + }, + }, + { + id: generateRandomID(), + delayMs: 0, + skipRenderWait: false, + param: { + type: PAGE_ACTION_CONTROL.end, + label: "End", + }, + }, + ] + + const windowPosition = await getWindowPosition() + const screen = await getScreenSize() + + Ipc.send(BgCommand.openAndRunPageAction, { + commandId: command.id, + url: { + searchUrl: service.url, + selectionText, + useClipboard: false, + }, + steps, + top: Math.floor(windowPosition.top + position.y), + left: Math.floor(windowPosition.left + position.x), + height: (command as any).popupOption?.height ?? PopupOption.height, + width: (command as any).popupOption?.width ?? PopupOption.width, + screen, + selectedText: selectionText, + srcUrl: location.href, + openMode, + }) + }, +} diff --git a/packages/extension/src/action/index.ts b/packages/extension/src/action/index.ts index f7d2aded..2ecfb215 100644 --- a/packages/extension/src/action/index.ts +++ b/packages/extension/src/action/index.ts @@ -8,6 +8,7 @@ import { Api } from "./api" import { SelectedLinkPopup } from "./selectedLinkPopup" import { Copy } from "./copy" import { PageAction } from "./pageAction" +import { AiPrompt } from "./aiPrompt" import { Option } from "./option" import { GetStyles as GetTextStyles } from "./getStyles" import { AddPageRule } from "./addPageRule" @@ -24,6 +25,7 @@ export const actions = { [OPEN_MODE.LINK_POPUP]: SelectedLinkPopup, [OPEN_MODE.COPY]: Copy, [OPEN_MODE.PAGE_ACTION]: PageAction, + [OPEN_MODE.AI_PROMPT]: AiPrompt, [OPEN_MODE.GET_TEXT_STYLES]: GetTextStyles, [OPEN_MODE.OPTION]: Option, [OPEN_MODE.ADD_PAGE_RULE]: AddPageRule, diff --git a/packages/extension/src/components/option/editor/AiPromptSection.tsx b/packages/extension/src/components/option/editor/AiPromptSection.tsx new file mode 100644 index 00000000..05a68f3a --- /dev/null +++ b/packages/extension/src/components/option/editor/AiPromptSection.tsx @@ -0,0 +1,99 @@ +import { useState, useEffect, useRef } from "react" +import { + FormControl, + FormField, + FormItem, + FormLabel, + FormDescription, + FormMessage, +} from "@/components/ui/form" +import { Textarea } from "@/components/ui/textarea" +import { OpenModeToggleField } from "@/components/option/field/OpenModeToggleField" +import { SelectField } from "@/components/option/field/SelectField" +import { InputMenu } from "@/components/pageAction/InputPopup" +import { AI_SERVICES } from "@/services/aiPrompt" +import { t as _t } from "@/services/i18n" +const t = (key: string, p?: string[]) => _t(`Option_${key}`, p) + +type AiPromptSectionProps = { + form: any +} + +export const AiPromptSection = ({ form }: AiPromptSectionProps) => { + const { register } = form + const [textarea, setTextarea] = useState(null) + const textareaRef = useRef(null) + + const updateHeight = (elm: HTMLTextAreaElement) => { + elm.style.height = "5px" + elm.style.height = elm.scrollHeight + "px" + } + + useEffect(() => { + if (textareaRef.current) { + updateHeight(textareaRef.current) + } + }, []) + + const serviceOptions = AI_SERVICES.map((s) => ({ + name: s.name, + value: s.id, + })) + + return ( + <> + + + + + ( + +
+ {t("aiPrompt_prompt")} + {t("aiPrompt_prompt_desc")} +
+
+ + +