mirror of
https://github.com/Direct-Dev-Ru/go-lcg.git
synced 2025-11-16 01:29:55 +00:00
improoved version
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -14,3 +14,4 @@ bin-linux-amd64/*
|
||||
bin-linux-arm64/*
|
||||
binaries-for-upload/*
|
||||
gpt_results
|
||||
shell-code/jwt.admin.token
|
||||
|
||||
@@ -2,7 +2,8 @@ FROM --platform=${BUILDPLATFORM} golang:1.24.6-alpine3.22 AS builder
|
||||
|
||||
ARG TARGETARCH
|
||||
|
||||
RUN apk add git && go install mvdan.cc/garble@latest
|
||||
RUN apk add git
|
||||
#&& go install mvdan.cc/garble@latest
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
@@ -11,8 +12,8 @@ COPY . .
|
||||
RUN echo $BUILDPLATFORM > buildplatform
|
||||
RUN echo $TARGETARCH > targetarch
|
||||
|
||||
# RUN GOOS=linux GOARCH=$TARGETARCH go build -o /app/go-lcg .
|
||||
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} garble -literals -tiny build -ldflags="-w -s" -o /app/go-lcg .
|
||||
RUN GOOS=linux GOARCH=$TARGETARCH go build -ldflags="-w -s" -o /app/go-lcg .
|
||||
#RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} garble -literals -tiny build -ldflags="-w -s" -o /app/go-lcg .
|
||||
|
||||
FROM alpine:latest
|
||||
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
FROM --platform=${BUILDPLATFORM} golang:1.24.6-alpine3.22 AS build
|
||||
ARG TARGETOS
|
||||
ARG TARGETARCH
|
||||
RUN apk add git && go install mvdan.cc/garble@latest
|
||||
# RUN apk add git
|
||||
#&& go install mvdan.cc/garble@latest
|
||||
WORKDIR /src
|
||||
ENV CGO_ENABLED=0
|
||||
COPY go.* .
|
||||
RUN go mod download
|
||||
COPY . .
|
||||
|
||||
# RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -o /out/go-lcg .
|
||||
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} garble -literals -tiny build -ldflags="-w -s" -o /out/go-lcg .
|
||||
RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} go build -ldflags="-w -s -buildid=" -trimpath -o /out/go-lcg .
|
||||
# RUN GOOS=${TARGETOS} GOARCH=${TARGETARCH} garble -literals -tiny build -ldflags="-w -s" -o /out/go-lcg .
|
||||
|
||||
FROM scratch AS bin-unix
|
||||
COPY --from=build /out/go-lcg /lcg
|
||||
|
||||
@@ -1 +1 @@
|
||||
v1.0.1
|
||||
v1.1.0
|
||||
|
||||
17
gpt/gpt.go
17
gpt/gpt.go
@@ -151,8 +151,8 @@ func (gpt3 *Gpt3) DeleteKey() {
|
||||
}
|
||||
|
||||
func (gpt3 *Gpt3) InitKey() {
|
||||
// Для proxy провайдера не нужен API ключ, используется JWT токен
|
||||
if gpt3.ProviderType == "proxy" {
|
||||
// Для ollama и proxy провайдеров не нужен API ключ
|
||||
if gpt3.ProviderType == "ollama" || gpt3.ProviderType == "proxy" {
|
||||
return
|
||||
}
|
||||
|
||||
@@ -167,16 +167,16 @@ func (gpt3 *Gpt3) InitKey() {
|
||||
}
|
||||
|
||||
// NewGpt3 создает новый экземпляр GPT с выбранным провайдером
|
||||
func NewGpt3(providerType, host, apiKey, model, prompt string, temperature float64) *Gpt3 {
|
||||
func NewGpt3(providerType, host, apiKey, model, prompt string, temperature float64, timeout int) *Gpt3 {
|
||||
var provider Provider
|
||||
|
||||
switch providerType {
|
||||
case "proxy":
|
||||
provider = NewProxyAPIProvider(host, apiKey, model) // apiKey используется как JWT токен
|
||||
provider = NewProxyAPIProvider(host, apiKey, model, timeout) // apiKey используется как JWT токен
|
||||
case "ollama":
|
||||
provider = NewOllamaProvider(host, model, temperature)
|
||||
provider = NewOllamaProvider(host, model, temperature, timeout)
|
||||
default:
|
||||
provider = NewOllamaProvider(host, model, temperature)
|
||||
provider = NewOllamaProvider(host, model, temperature, timeout)
|
||||
}
|
||||
|
||||
return &Gpt3{
|
||||
@@ -209,3 +209,8 @@ func (gpt3 *Gpt3) Completions(ask string) string {
|
||||
func (gpt3 *Gpt3) Health() error {
|
||||
return gpt3.Provider.Health()
|
||||
}
|
||||
|
||||
// GetAvailableModels возвращает список доступных моделей
|
||||
func (gpt3 *Gpt3) GetAvailableModels() ([]string, error) {
|
||||
return gpt3.Provider.GetAvailableModels()
|
||||
}
|
||||
|
||||
203
gpt/prompts.go
Normal file
203
gpt/prompts.go
Normal file
@@ -0,0 +1,203 @@
|
||||
package gpt
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// SystemPrompt представляет системный промпт
|
||||
type SystemPrompt struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Description string `json:"description"`
|
||||
Content string `json:"content"`
|
||||
}
|
||||
|
||||
// PromptManager управляет системными промптами
|
||||
type PromptManager struct {
|
||||
Prompts []SystemPrompt
|
||||
ConfigFile string
|
||||
HomeDir string
|
||||
}
|
||||
|
||||
// NewPromptManager создает новый менеджер промптов
|
||||
func NewPromptManager(homeDir string) *PromptManager {
|
||||
configFile := filepath.Join(homeDir, ".lcg_prompts.json")
|
||||
|
||||
pm := &PromptManager{
|
||||
ConfigFile: configFile,
|
||||
HomeDir: homeDir,
|
||||
}
|
||||
|
||||
// Загружаем предустановленные промпты
|
||||
pm.loadDefaultPrompts()
|
||||
|
||||
// Загружаем пользовательские промпты
|
||||
pm.loadCustomPrompts()
|
||||
|
||||
return pm
|
||||
}
|
||||
|
||||
// loadDefaultPrompts загружает предустановленные промпты
|
||||
func (pm *PromptManager) loadDefaultPrompts() {
|
||||
defaultPrompts := []SystemPrompt{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "linux-command",
|
||||
Description: "Generate Linux commands (default)",
|
||||
Content: "Reply with linux command and nothing else. Output with plain response - no need formatting. No need explanation. No need code blocks. No need ` symbols.",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "linux-command-with-explanation",
|
||||
Description: "Generate Linux commands with explanation",
|
||||
Content: "Generate a Linux command and provide a brief explanation of what it does. Format: COMMAND: explanation",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "linux-command-safe",
|
||||
Description: "Generate safe Linux commands",
|
||||
Content: "Generate a safe Linux command that won't cause data loss or system damage. Reply with linux command and nothing else. Output with plain response - no need formatting.",
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
Name: "linux-command-verbose",
|
||||
Description: "Generate Linux commands with detailed explanation",
|
||||
Content: "Generate a Linux command and provide detailed explanation including what each flag does and potential alternatives.",
|
||||
},
|
||||
{
|
||||
ID: 5,
|
||||
Name: "linux-command-simple",
|
||||
Description: "Generate simple Linux commands",
|
||||
Content: "Generate a simple, easy-to-understand Linux command. Avoid complex flags and options when possible.",
|
||||
},
|
||||
}
|
||||
|
||||
pm.Prompts = defaultPrompts
|
||||
}
|
||||
|
||||
// loadCustomPrompts загружает пользовательские промпты из файла
|
||||
func (pm *PromptManager) loadCustomPrompts() {
|
||||
if _, err := os.Stat(pm.ConfigFile); os.IsNotExist(err) {
|
||||
return
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(pm.ConfigFile)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
var customPrompts []SystemPrompt
|
||||
if err := json.Unmarshal(data, &customPrompts); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Добавляем пользовательские промпты с новыми ID
|
||||
for i, prompt := range customPrompts {
|
||||
prompt.ID = len(pm.Prompts) + i + 1
|
||||
pm.Prompts = append(pm.Prompts, prompt)
|
||||
}
|
||||
}
|
||||
|
||||
// saveCustomPrompts сохраняет пользовательские промпты
|
||||
func (pm *PromptManager) saveCustomPrompts() error {
|
||||
// Находим пользовательские промпты (ID > 5)
|
||||
var customPrompts []SystemPrompt
|
||||
for _, prompt := range pm.Prompts {
|
||||
if prompt.ID > 5 {
|
||||
customPrompts = append(customPrompts, prompt)
|
||||
}
|
||||
}
|
||||
|
||||
data, err := json.MarshalIndent(customPrompts, "", " ")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return os.WriteFile(pm.ConfigFile, data, 0644)
|
||||
}
|
||||
|
||||
// GetPromptByID возвращает промпт по ID
|
||||
func (pm *PromptManager) GetPromptByID(id int) (*SystemPrompt, error) {
|
||||
for _, prompt := range pm.Prompts {
|
||||
if prompt.ID == id {
|
||||
return &prompt, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("промпт с ID %d не найден", id)
|
||||
}
|
||||
|
||||
// GetPromptByName возвращает промпт по имени
|
||||
func (pm *PromptManager) GetPromptByName(name string) (*SystemPrompt, error) {
|
||||
for _, prompt := range pm.Prompts {
|
||||
if strings.EqualFold(prompt.Name, name) {
|
||||
return &prompt, nil
|
||||
}
|
||||
}
|
||||
return nil, fmt.Errorf("промпт с именем '%s' не найден", name)
|
||||
}
|
||||
|
||||
// ListPrompts выводит список всех доступных промптов
|
||||
func (pm *PromptManager) ListPrompts() {
|
||||
fmt.Println("Available system prompts:")
|
||||
fmt.Println("ID | Name | Description")
|
||||
fmt.Println("---+---------------------------+--------------------------------")
|
||||
|
||||
for _, prompt := range pm.Prompts {
|
||||
description := prompt.Description
|
||||
if len(description) > 80 {
|
||||
description = description[:77] + "..."
|
||||
}
|
||||
fmt.Printf("%-2d | %-25s | %s\n",
|
||||
prompt.ID,
|
||||
truncateString(prompt.Name, 25),
|
||||
description)
|
||||
}
|
||||
}
|
||||
|
||||
// AddCustomPrompt добавляет новый пользовательский промпт
|
||||
func (pm *PromptManager) AddCustomPrompt(name, description, content string) error {
|
||||
// Проверяем, что имя уникально
|
||||
for _, prompt := range pm.Prompts {
|
||||
if strings.EqualFold(prompt.Name, name) {
|
||||
return fmt.Errorf("промпт с именем '%s' уже существует", name)
|
||||
}
|
||||
}
|
||||
|
||||
newPrompt := SystemPrompt{
|
||||
ID: len(pm.Prompts) + 1,
|
||||
Name: name,
|
||||
Description: description,
|
||||
Content: content,
|
||||
}
|
||||
|
||||
pm.Prompts = append(pm.Prompts, newPrompt)
|
||||
return pm.saveCustomPrompts()
|
||||
}
|
||||
|
||||
// DeleteCustomPrompt удаляет пользовательский промпт
|
||||
func (pm *PromptManager) DeleteCustomPrompt(id int) error {
|
||||
if id <= 5 {
|
||||
return fmt.Errorf("нельзя удалить предустановленный промпт")
|
||||
}
|
||||
|
||||
for i, prompt := range pm.Prompts {
|
||||
if prompt.ID == id {
|
||||
pm.Prompts = append(pm.Prompts[:i], pm.Prompts[i+1:]...)
|
||||
return pm.saveCustomPrompts()
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("промпт с ID %d не найден", id)
|
||||
}
|
||||
|
||||
// truncateString обрезает строку до указанной длины
|
||||
func truncateString(s string, maxLen int) string {
|
||||
if len(s) <= maxLen {
|
||||
return s
|
||||
}
|
||||
return s[:maxLen-3] + "..."
|
||||
}
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
type Provider interface {
|
||||
Chat(messages []Chat) (string, error)
|
||||
Health() error
|
||||
GetAvailableModels() ([]string, error)
|
||||
}
|
||||
|
||||
// ProxyAPIProvider реализация для прокси API (gin-restapi)
|
||||
@@ -66,21 +67,30 @@ type OllamaProvider struct {
|
||||
HTTPClient *http.Client
|
||||
}
|
||||
|
||||
func NewProxyAPIProvider(baseURL, jwtToken, model string) *ProxyAPIProvider {
|
||||
// OllamaTagsResponse структура ответа для получения списка моделей
|
||||
type OllamaTagsResponse struct {
|
||||
Models []struct {
|
||||
Name string `json:"name"`
|
||||
ModifiedAt string `json:"modified_at"`
|
||||
Size int64 `json:"size"`
|
||||
} `json:"models"`
|
||||
}
|
||||
|
||||
func NewProxyAPIProvider(baseURL, jwtToken, model string, timeout int) *ProxyAPIProvider {
|
||||
return &ProxyAPIProvider{
|
||||
BaseURL: strings.TrimSuffix(baseURL, "/"),
|
||||
JWTToken: jwtToken,
|
||||
Model: model,
|
||||
HTTPClient: &http.Client{Timeout: 120 * time.Second},
|
||||
HTTPClient: &http.Client{Timeout: time.Duration(timeout) * time.Second},
|
||||
}
|
||||
}
|
||||
|
||||
func NewOllamaProvider(baseURL, model string, temperature float64) *OllamaProvider {
|
||||
func NewOllamaProvider(baseURL, model string, temperature float64, timeout int) *OllamaProvider {
|
||||
return &OllamaProvider{
|
||||
BaseURL: strings.TrimSuffix(baseURL, "/"),
|
||||
Model: model,
|
||||
Temperature: temperature,
|
||||
HTTPClient: &http.Client{Timeout: 120 * time.Second},
|
||||
HTTPClient: &http.Client{Timeout: time.Duration(timeout) * time.Second},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -244,3 +254,43 @@ func (o *OllamaProvider) Health() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAvailableModels для ProxyAPIProvider возвращает фиксированный список
|
||||
func (p *ProxyAPIProvider) GetAvailableModels() ([]string, error) {
|
||||
return []string{"GigaChat-2", "GigaChat-2-Pro", "GigaChat-2-Max"}, nil
|
||||
}
|
||||
|
||||
// GetAvailableModels возвращает список доступных моделей для провайдера
|
||||
func (o *OllamaProvider) GetAvailableModels() ([]string, error) {
|
||||
req, err := http.NewRequest("GET", o.BaseURL+"/api/tags", nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ошибка создания запроса: %w", err)
|
||||
}
|
||||
|
||||
resp, err := o.HTTPClient.Do(req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ошибка получения моделей: %w", err)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ошибка чтения ответа: %w", err)
|
||||
}
|
||||
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return nil, fmt.Errorf("ошибка API: %d - %s", resp.StatusCode, string(body))
|
||||
}
|
||||
|
||||
var response OllamaTagsResponse
|
||||
if err := json.Unmarshal(body, &response); err != nil {
|
||||
return nil, fmt.Errorf("ошибка парсинга ответа: %w", err)
|
||||
}
|
||||
|
||||
var models []string
|
||||
for _, model := range response.Models {
|
||||
models = append(models, model.Name)
|
||||
}
|
||||
|
||||
return models, nil
|
||||
}
|
||||
|
||||
224
main.go
224
main.go
@@ -8,6 +8,7 @@ import (
|
||||
"os/exec"
|
||||
"os/user"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -30,6 +31,8 @@ var (
|
||||
RESULT_FOLDER = getEnv("LCG_RESULT_FOLDER", path.Join(cwd, "gpt_results"))
|
||||
PROVIDER_TYPE = getEnv("LCG_PROVIDER", "ollama") // "ollama", "proxy"
|
||||
JWT_TOKEN = getEnv("LCG_JWT_TOKEN", "")
|
||||
PROMPT_ID = getEnv("LCG_PROMPT_ID", "1") // ID промпта по умолчанию
|
||||
TIMEOUT = getEnv("LCG_TIMEOUT", "120") // Таймаут в секундах по умолчанию
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -76,21 +79,50 @@ Linux Command GPT - инструмент для генерации Linux ком
|
||||
&cli.StringFlag{
|
||||
Name: "sys",
|
||||
Aliases: []string{"s"},
|
||||
Usage: "System prompt",
|
||||
DefaultText: getEnv("LCG_PROMPT", "Reply with linux command and nothing else. Output with plain response - no need formatting. No need explanation. No need code blocks"),
|
||||
Value: getEnv("LCG_PROMPT", "Reply with linux command and nothing else. Output with plain response - no need formatting. No need explanation. No need code blocks"),
|
||||
Usage: "System prompt content or ID",
|
||||
DefaultText: "Use prompt ID from LCG_PROMPT_ID or default prompt",
|
||||
Value: "",
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "prompt-id",
|
||||
Aliases: []string{"pid"},
|
||||
Usage: "System prompt ID (1-5 for default prompts)",
|
||||
DefaultText: "1",
|
||||
Value: 1,
|
||||
},
|
||||
&cli.IntFlag{
|
||||
Name: "timeout",
|
||||
Aliases: []string{"t"},
|
||||
Usage: "Request timeout in seconds",
|
||||
DefaultText: "120",
|
||||
Value: 120,
|
||||
},
|
||||
},
|
||||
Action: func(c *cli.Context) error {
|
||||
file := c.String("file")
|
||||
system := c.String("sys")
|
||||
promptID := c.Int("prompt-id")
|
||||
timeout := c.Int("timeout")
|
||||
args := c.Args().Slice()
|
||||
|
||||
if len(args) == 0 {
|
||||
cli.ShowAppHelp(c)
|
||||
showTips()
|
||||
return nil
|
||||
}
|
||||
executeMain(file, system, strings.Join(args, " "))
|
||||
|
||||
// Если указан prompt-id, загружаем соответствующий промпт
|
||||
if system == "" && promptID > 0 {
|
||||
currentUser, _ := user.Current()
|
||||
pm := gpt.NewPromptManager(currentUser.HomeDir)
|
||||
if prompt, err := pm.GetPromptByID(promptID); err == nil {
|
||||
system = prompt.Content
|
||||
} else {
|
||||
fmt.Printf("Warning: Prompt ID %d not found, using default prompt\n", promptID)
|
||||
}
|
||||
}
|
||||
|
||||
executeMain(file, system, strings.Join(args, " "), timeout)
|
||||
return nil
|
||||
},
|
||||
}
|
||||
@@ -117,7 +149,15 @@ func getCommands() []*cli.Command {
|
||||
Aliases: []string{"u"},
|
||||
Usage: "Update the API key",
|
||||
Action: func(c *cli.Context) error {
|
||||
gpt3 := initGPT(PROMPT)
|
||||
if PROVIDER_TYPE == "ollama" || PROVIDER_TYPE == "proxy" {
|
||||
fmt.Println("API key is not needed for ollama and proxy providers")
|
||||
return nil
|
||||
}
|
||||
timeout := 120 // default timeout
|
||||
if t, err := strconv.Atoi(TIMEOUT); err == nil {
|
||||
timeout = t
|
||||
}
|
||||
gpt3 := initGPT(PROMPT, timeout)
|
||||
gpt3.UpdateKey()
|
||||
fmt.Println("API key updated.")
|
||||
return nil
|
||||
@@ -128,7 +168,15 @@ func getCommands() []*cli.Command {
|
||||
Aliases: []string{"d"},
|
||||
Usage: "Delete the API key",
|
||||
Action: func(c *cli.Context) error {
|
||||
gpt3 := initGPT(PROMPT)
|
||||
if PROVIDER_TYPE == "ollama" || PROVIDER_TYPE == "proxy" {
|
||||
fmt.Println("API key is not needed for ollama and proxy providers")
|
||||
return nil
|
||||
}
|
||||
timeout := 120 // default timeout
|
||||
if t, err := strconv.Atoi(TIMEOUT); err == nil {
|
||||
timeout = t
|
||||
}
|
||||
gpt3 := initGPT(PROMPT, timeout)
|
||||
gpt3.DeleteKey()
|
||||
fmt.Println("API key deleted.")
|
||||
return nil
|
||||
@@ -180,12 +228,39 @@ func getCommands() []*cli.Command {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "models",
|
||||
Aliases: []string{"m"},
|
||||
Usage: "Show available models",
|
||||
Action: func(c *cli.Context) error {
|
||||
timeout := 120 // default timeout
|
||||
if t, err := strconv.Atoi(TIMEOUT); err == nil {
|
||||
timeout = t
|
||||
}
|
||||
gpt3 := initGPT(PROMPT, timeout)
|
||||
models, err := gpt3.GetAvailableModels()
|
||||
if err != nil {
|
||||
fmt.Printf("Ошибка получения моделей: %v\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Доступные модели для провайдера %s:\n", PROVIDER_TYPE)
|
||||
for i, model := range models {
|
||||
fmt.Printf(" %d. %s\n", i+1, model)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "health",
|
||||
Aliases: []string{"he"}, // Изменено с "h" на "he"
|
||||
Usage: "Check API health",
|
||||
Action: func(c *cli.Context) error {
|
||||
gpt3 := initGPT(PROMPT)
|
||||
timeout := 120 // default timeout
|
||||
if t, err := strconv.Atoi(TIMEOUT); err == nil {
|
||||
timeout = t
|
||||
}
|
||||
gpt3 := initGPT(PROMPT, timeout)
|
||||
if err := gpt3.Health(); err != nil {
|
||||
fmt.Printf("Health check failed: %v\n", err)
|
||||
return err
|
||||
@@ -203,6 +278,7 @@ func getCommands() []*cli.Command {
|
||||
fmt.Printf("Host: %s\n", HOST)
|
||||
fmt.Printf("Model: %s\n", MODEL)
|
||||
fmt.Printf("Prompt: %s\n", PROMPT)
|
||||
fmt.Printf("Timeout: %s seconds\n", TIMEOUT)
|
||||
if PROVIDER_TYPE == "proxy" {
|
||||
fmt.Printf("JWT Token: %s\n", func() string {
|
||||
if JWT_TOKEN != "" {
|
||||
@@ -228,10 +304,126 @@ func getCommands() []*cli.Command {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "prompts",
|
||||
Aliases: []string{"p"},
|
||||
Usage: "Manage system prompts",
|
||||
Subcommands: []*cli.Command{
|
||||
{
|
||||
Name: "list",
|
||||
Aliases: []string{"l"},
|
||||
Usage: "List all available prompts",
|
||||
Action: func(c *cli.Context) error {
|
||||
currentUser, _ := user.Current()
|
||||
pm := gpt.NewPromptManager(currentUser.HomeDir)
|
||||
pm.ListPrompts()
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "add",
|
||||
Aliases: []string{"a"},
|
||||
Usage: "Add a new custom prompt",
|
||||
Action: func(c *cli.Context) error {
|
||||
currentUser, _ := user.Current()
|
||||
pm := gpt.NewPromptManager(currentUser.HomeDir)
|
||||
|
||||
var name, description, content string
|
||||
|
||||
fmt.Print("Название промпта: ")
|
||||
fmt.Scanln(&name)
|
||||
|
||||
fmt.Print("Описание: ")
|
||||
fmt.Scanln(&description)
|
||||
|
||||
fmt.Print("Содержание промпта: ")
|
||||
fmt.Scanln(&content)
|
||||
|
||||
if err := pm.AddCustomPrompt(name, description, content); err != nil {
|
||||
fmt.Printf("Ошибка добавления промпта: %v\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Промпт успешно добавлен!")
|
||||
return nil
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "delete",
|
||||
Aliases: []string{"d"},
|
||||
Usage: "Delete a custom prompt",
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.NArg() == 0 {
|
||||
fmt.Println("Укажите ID промпта для удаления")
|
||||
return nil
|
||||
}
|
||||
|
||||
var id int
|
||||
if _, err := fmt.Sscanf(c.Args().First(), "%d", &id); err != nil {
|
||||
fmt.Println("Неверный ID промпта")
|
||||
return err
|
||||
}
|
||||
|
||||
currentUser, _ := user.Current()
|
||||
pm := gpt.NewPromptManager(currentUser.HomeDir)
|
||||
|
||||
if err := pm.DeleteCustomPrompt(id); err != nil {
|
||||
fmt.Printf("Ошибка удаления промпта: %v\n", err)
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Println("Промпт успешно удален!")
|
||||
return nil
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "test-prompt",
|
||||
Aliases: []string{"tp"},
|
||||
Usage: "Test a specific prompt ID",
|
||||
Action: func(c *cli.Context) error {
|
||||
if c.NArg() == 0 {
|
||||
fmt.Println("Usage: lcg test-prompt <prompt-id> <command>")
|
||||
return nil
|
||||
}
|
||||
|
||||
var promptID int
|
||||
if _, err := fmt.Sscanf(c.Args().First(), "%d", &promptID); err != nil {
|
||||
fmt.Println("Invalid prompt ID")
|
||||
return err
|
||||
}
|
||||
|
||||
currentUser, _ := user.Current()
|
||||
pm := gpt.NewPromptManager(currentUser.HomeDir)
|
||||
|
||||
prompt, err := pm.GetPromptByID(promptID)
|
||||
if err != nil {
|
||||
fmt.Printf("Prompt ID %d not found\n", promptID)
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Testing prompt ID %d: %s\n", promptID, prompt.Name)
|
||||
fmt.Printf("Description: %s\n", prompt.Description)
|
||||
fmt.Printf("Content: %s\n", prompt.Content)
|
||||
|
||||
if len(c.Args().Slice()) > 1 {
|
||||
command := strings.Join(c.Args().Slice()[1:], " ")
|
||||
fmt.Printf("\nTesting with command: %s\n", command)
|
||||
timeout := 120 // default timeout
|
||||
if t, err := strconv.Atoi(TIMEOUT); err == nil {
|
||||
timeout = t
|
||||
}
|
||||
executeMain("", prompt.Content, command, timeout)
|
||||
}
|
||||
|
||||
return nil
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func executeMain(file, system, commandInput string) {
|
||||
func executeMain(file, system, commandInput string, timeout int) {
|
||||
if file != "" {
|
||||
if err := reader.FileToPrompt(&commandInput, file); err != nil {
|
||||
printColored(fmt.Sprintf("❌ Ошибка чтения файла: %v\n", err), colorRed)
|
||||
@@ -239,6 +431,11 @@ func executeMain(file, system, commandInput string) {
|
||||
}
|
||||
}
|
||||
|
||||
// Если system пустой, используем дефолтный промпт
|
||||
if system == "" {
|
||||
system = PROMPT
|
||||
}
|
||||
|
||||
if _, err := os.Stat(RESULT_FOLDER); os.IsNotExist(err) {
|
||||
if err := os.MkdirAll(RESULT_FOLDER, 0755); err != nil {
|
||||
printColored(fmt.Sprintf("❌ Ошибка создания папки результатов: %v\n", err), colorRed)
|
||||
@@ -246,7 +443,7 @@ func executeMain(file, system, commandInput string) {
|
||||
}
|
||||
}
|
||||
|
||||
gpt3 := initGPT(system)
|
||||
gpt3 := initGPT(system, timeout)
|
||||
|
||||
printColored("🤖 Запрос: ", colorCyan)
|
||||
fmt.Printf("%s\n", commandInput)
|
||||
@@ -265,7 +462,7 @@ func executeMain(file, system, commandInput string) {
|
||||
handlePostResponse(response, gpt3, system, commandInput)
|
||||
}
|
||||
|
||||
func initGPT(system string) gpt.Gpt3 {
|
||||
func initGPT(system string, timeout int) gpt.Gpt3 {
|
||||
currentUser, _ := user.Current()
|
||||
|
||||
// Загружаем JWT токен в зависимости от провайдера
|
||||
@@ -281,7 +478,7 @@ func initGPT(system string) gpt.Gpt3 {
|
||||
}
|
||||
}
|
||||
|
||||
return *gpt.NewGpt3(PROVIDER_TYPE, HOST, jwtToken, MODEL, system, 0.01)
|
||||
return *gpt.NewGpt3(PROVIDER_TYPE, HOST, jwtToken, MODEL, system, 0.01, timeout)
|
||||
}
|
||||
|
||||
func getCommand(gpt3 gpt.Gpt3, cmd string) (string, float64) {
|
||||
@@ -326,7 +523,7 @@ func handlePostResponse(response string, gpt3 gpt.Gpt3, system, cmd string) {
|
||||
saveResponse(response, gpt3, cmd)
|
||||
case "r":
|
||||
fmt.Println("🔄 Перегенерирую...")
|
||||
executeMain("", system, cmd)
|
||||
executeMain("", system, cmd, 120) // Use default timeout for regeneration
|
||||
case "e":
|
||||
executeCommand(response)
|
||||
default:
|
||||
@@ -420,6 +617,9 @@ func showTips() {
|
||||
printColored("💡 Подсказки:\n", colorCyan)
|
||||
fmt.Println(" • Используйте --file для чтения из файла")
|
||||
fmt.Println(" • Используйте --sys для изменения системного промпта")
|
||||
fmt.Println(" • Используйте --prompt-id для выбора предустановленного промпта")
|
||||
fmt.Println(" • Используйте --timeout для установки таймаута запроса")
|
||||
fmt.Println(" • Команда 'prompts list' покажет все доступные промпты")
|
||||
fmt.Println(" • Команда 'history' покажет историю запросов")
|
||||
fmt.Println(" • Команда 'config' покажет текущие настройки")
|
||||
fmt.Println(" • Команда 'health' проверит доступность API")
|
||||
|
||||
6
shell-code/run-with-proxy.sh
Normal file
6
shell-code/run-with-proxy.sh
Normal file
@@ -0,0 +1,6 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
# shellcheck disable=SC2034
|
||||
LCG_PROVIDER=proxy LCG_HOST=http://localhost:8080 LCG_MODEL=GigaChat-2-Max LCG_JWT_TOKEN=$(go-ansible-vault -a -i shell-code/jwt.admin.token get -m 'JWT_TOKEN' -q) go run . $1 $2 $3 $4 $5 $6 $7 $8 $9
|
||||
|
||||
LCG_PROVIDER=proxy LCG_HOST=https://direct-dev.ru LCG_MODEL=GigaChat-2-Max LCG_JWT_TOKEN=$(go-ansible-vault --key $(cat ~/.config/gak) -i ~/.config/jwt.direct-dev.ru get -m 'JWT_TOKEN' -q) go run . [your question here]
|
||||
Reference in New Issue
Block a user