mirror of
https://github.com/Direct-Dev-Ru/go-lcg.git
synced 2025-11-16 01:29:55 +00:00
mobile version styled -ready for new version 2.0.1
This commit is contained in:
421
serve/prompts.go
Normal file
421
serve/prompts.go
Normal file
@@ -0,0 +1,421 @@
|
||||
package serve
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"net/http"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/direct-dev-ru/linux-command-gpt/gpt"
|
||||
"github.com/direct-dev-ru/linux-command-gpt/serve/templates"
|
||||
)
|
||||
|
||||
// VerbosePrompt структура для промптов подробности
|
||||
type VerbosePrompt struct {
|
||||
Mode string
|
||||
Name string
|
||||
Description string
|
||||
Content string
|
||||
IsDefault bool
|
||||
}
|
||||
|
||||
// handlePromptsPage обрабатывает страницу управления промптами
|
||||
func handlePromptsPage(w http.ResponseWriter, r *http.Request) {
|
||||
// Получаем домашнюю директорию пользователя
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
http.Error(w, "Ошибка получения домашней директории", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Создаем менеджер промптов (использует конфигурацию из config.AppConfig.PromptFolder)
|
||||
pm := gpt.NewPromptManager(homeDir)
|
||||
|
||||
// Получаем язык из параметра запроса, если не указан - берем из файла
|
||||
lang := r.URL.Query().Get("lang")
|
||||
if lang == "" {
|
||||
lang = pm.GetCurrentLanguage()
|
||||
}
|
||||
|
||||
tmpl := templates.PromptsPageTemplate
|
||||
|
||||
t, err := template.New("prompts").Parse(tmpl)
|
||||
if err != nil {
|
||||
http.Error(w, "Ошибка шаблона", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Создаем структуру с дополнительным полем IsDefault
|
||||
type PromptWithDefault struct {
|
||||
gpt.SystemPrompt
|
||||
IsDefault bool
|
||||
}
|
||||
|
||||
// Получаем текущий язык из файла
|
||||
currentLang := pm.GetCurrentLanguage()
|
||||
|
||||
// Если язык не указан в URL, используем язык из файла
|
||||
if lang == "" {
|
||||
lang = currentLang
|
||||
}
|
||||
|
||||
// Получаем системные промпты с учетом языка
|
||||
systemPrompts := getSystemPromptsWithLang(pm.Prompts, lang)
|
||||
|
||||
var promptsWithDefault []PromptWithDefault
|
||||
for _, prompt := range systemPrompts {
|
||||
// Показываем только системные промпты (ID 1-5) на первой вкладке
|
||||
if prompt.ID >= 1 && prompt.ID <= 5 {
|
||||
// Проверяем, является ли промпт встроенным и неизмененным
|
||||
isDefault := gpt.IsBuiltinPrompt(prompt)
|
||||
promptsWithDefault = append(promptsWithDefault, PromptWithDefault{
|
||||
SystemPrompt: prompt,
|
||||
IsDefault: isDefault,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Получаем промпты подробности из файла sys_prompts
|
||||
verbosePrompts := getVerbosePromptsFromFile(pm.Prompts, lang)
|
||||
|
||||
data := struct {
|
||||
Prompts []PromptWithDefault
|
||||
VerbosePrompts []VerbosePrompt
|
||||
Lang string
|
||||
}{
|
||||
Prompts: promptsWithDefault,
|
||||
VerbosePrompts: verbosePrompts,
|
||||
Lang: lang,
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "text/html; charset=utf-8")
|
||||
t.Execute(w, data)
|
||||
}
|
||||
|
||||
// handleAddPrompt обрабатывает добавление нового промпта
|
||||
func handleAddPrompt(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// Получаем домашнюю директорию пользователя
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
http.Error(w, "Ошибка получения домашней директории", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Создаем менеджер промптов (использует конфигурацию из config.AppConfig.PromptFolder)
|
||||
pm := gpt.NewPromptManager(homeDir)
|
||||
|
||||
// Парсим JSON данные
|
||||
var promptData struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&promptData); err != nil {
|
||||
http.Error(w, "Ошибка парсинга JSON", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Добавляем промпт
|
||||
if err := pm.AddPrompt(promptData.Name, promptData.Description, promptData.Content); err != nil {
|
||||
http.Error(w, fmt.Sprintf("Ошибка добавления промпта: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("Промпт успешно добавлен"))
|
||||
}
|
||||
|
||||
// handleEditPrompt обрабатывает редактирование промпта
|
||||
func handleEditPrompt(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "PUT" {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// Получаем ID из URL
|
||||
idStr := strings.TrimPrefix(r.URL.Path, "/prompts/edit/")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
http.Error(w, "Неверный ID промпта", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Получаем домашнюю директорию пользователя
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
http.Error(w, "Ошибка получения домашней директории", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Создаем менеджер промптов (использует конфигурацию из config.AppConfig.PromptFolder)
|
||||
pm := gpt.NewPromptManager(homeDir)
|
||||
|
||||
// Парсим JSON данные
|
||||
var promptData struct {
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&promptData); err != nil {
|
||||
http.Error(w, "Ошибка парсинга JSON", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Обновляем промпт
|
||||
if err := pm.UpdatePrompt(id, promptData.Name, promptData.Description, promptData.Content); err != nil {
|
||||
http.Error(w, fmt.Sprintf("Ошибка обновления промпта: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("Промпт успешно обновлен"))
|
||||
}
|
||||
|
||||
// handleDeletePrompt обрабатывает удаление промпта
|
||||
func handleDeletePrompt(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "DELETE" {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// Получаем ID из URL
|
||||
idStr := strings.TrimPrefix(r.URL.Path, "/prompts/delete/")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
http.Error(w, "Неверный ID промпта", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Получаем домашнюю директорию пользователя
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
http.Error(w, "Ошибка получения домашней директории", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Создаем менеджер промптов (использует конфигурацию из config.AppConfig.PromptFolder)
|
||||
pm := gpt.NewPromptManager(homeDir)
|
||||
|
||||
// Удаляем промпт
|
||||
if err := pm.DeletePrompt(id); err != nil {
|
||||
http.Error(w, fmt.Sprintf("Ошибка удаления промпта: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("Промпт успешно удален"))
|
||||
}
|
||||
|
||||
// handleRestorePrompt восстанавливает системный промпт к значению по умолчанию
|
||||
func handleRestorePrompt(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// Получаем ID из URL
|
||||
idStr := strings.TrimPrefix(r.URL.Path, "/prompts/restore/")
|
||||
id, err := strconv.Atoi(idStr)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid prompt ID", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Получаем домашнюю директорию пользователя
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
http.Error(w, "Ошибка получения домашней директории", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Создаем менеджер промптов
|
||||
pm := gpt.NewPromptManager(homeDir)
|
||||
|
||||
// Получаем текущий язык
|
||||
currentLang := pm.GetCurrentLanguage()
|
||||
|
||||
// Получаем встроенный промпт для текущего языка
|
||||
builtinPrompt := gpt.GetBuiltinPromptByIDAndLanguage(id, currentLang)
|
||||
if builtinPrompt == nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"success": false,
|
||||
"error": "Промпт не найден в встроенных",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Обновляем промпт в списке
|
||||
for i, prompt := range pm.Prompts {
|
||||
if prompt.ID == id {
|
||||
pm.Prompts[i] = *builtinPrompt
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Сохраняем изменения
|
||||
if err := pm.SaveAllPrompts(); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"success": false,
|
||||
"error": "Ошибка сохранения: " + err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"success": true,
|
||||
})
|
||||
}
|
||||
|
||||
// handleRestoreVerbosePrompt восстанавливает verbose промпт к значению по умолчанию
|
||||
func handleRestoreVerbosePrompt(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// Получаем режим из URL
|
||||
mode := strings.TrimPrefix(r.URL.Path, "/prompts/restore-verbose/")
|
||||
|
||||
// Получаем домашнюю директорию пользователя
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
http.Error(w, "Ошибка получения домашней директории", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Создаем менеджер промптов
|
||||
pm := gpt.NewPromptManager(homeDir)
|
||||
|
||||
// Получаем текущий язык
|
||||
currentLang := pm.GetCurrentLanguage()
|
||||
|
||||
// Определяем ID по режиму
|
||||
var id int
|
||||
switch mode {
|
||||
case "v":
|
||||
id = 6
|
||||
case "vv":
|
||||
id = 7
|
||||
case "vvv":
|
||||
id = 8
|
||||
default:
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"success": false,
|
||||
"error": "Неверный режим промпта",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Получаем встроенный промпт для текущего языка
|
||||
builtinPrompt := gpt.GetBuiltinPromptByIDAndLanguage(id, currentLang)
|
||||
if builtinPrompt == nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"success": false,
|
||||
"error": "Промпт не найден в встроенных",
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
// Обновляем промпт в списке
|
||||
for i, prompt := range pm.Prompts {
|
||||
if prompt.ID == id {
|
||||
pm.Prompts[i] = *builtinPrompt
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
// Сохраняем изменения
|
||||
if err := pm.SaveAllPrompts(); err != nil {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"success": false,
|
||||
"error": "Ошибка сохранения: " + err.Error(),
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"success": true,
|
||||
})
|
||||
}
|
||||
|
||||
// handleSaveLang обрабатывает сохранение промптов при переключении языка
|
||||
func handleSaveLang(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method != "POST" {
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
return
|
||||
}
|
||||
|
||||
// Получаем домашнюю директорию пользователя
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
http.Error(w, "Ошибка получения домашней директории", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// Создаем менеджер промптов
|
||||
pm := gpt.NewPromptManager(homeDir)
|
||||
|
||||
// Парсим JSON данные
|
||||
var langData struct {
|
||||
Lang string `json:"lang"`
|
||||
}
|
||||
|
||||
if err := json.NewDecoder(r.Body).Decode(&langData); err != nil {
|
||||
http.Error(w, "Ошибка парсинга JSON", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
// Устанавливаем язык файла
|
||||
pm.SetLanguage(langData.Lang)
|
||||
|
||||
// Переводим только встроенные промпты (по ID), а пользовательские оставляем как есть
|
||||
var translatedPrompts []gpt.SystemPrompt
|
||||
for _, p := range pm.Prompts {
|
||||
// Проверяем, является ли промпт встроенным по ID (1-8)
|
||||
if pm.IsDefaultPromptByID(p) {
|
||||
// System (1-5) и Verbose (6-8)
|
||||
if p.ID >= 1 && p.ID <= 5 {
|
||||
translatedPrompts = append(translatedPrompts, translateSystemPrompt(p, langData.Lang))
|
||||
} else if p.ID >= 6 && p.ID <= 8 {
|
||||
translatedPrompts = append(translatedPrompts, translateVerbosePrompt(p, langData.Lang))
|
||||
} else {
|
||||
translatedPrompts = append(translatedPrompts, p)
|
||||
}
|
||||
} else {
|
||||
// Пользовательские промпты (ID > 8) не трогаем
|
||||
translatedPrompts = append(translatedPrompts, p)
|
||||
}
|
||||
}
|
||||
|
||||
// Обновляем в pm и сохраняем
|
||||
pm.Prompts = translatedPrompts
|
||||
if err := pm.SaveAllPrompts(); err != nil {
|
||||
http.Error(w, fmt.Sprintf("Ошибка сохранения: %v", err), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("Промпты сохранены"))
|
||||
}
|
||||
Reference in New Issue
Block a user