| package types | |
| import ( | |
| "encoding/json" | |
| "fmt" | |
| "github.com/sashabaranov/go-openai" | |
| ) | |
| const ( | |
| ChatStreamV7 = "https://api.jetbrains.ai/user/v5/llm/chat/stream/v7" | |
| PROMPT = "ij.chat.request.new-chat" | |
| JwtTokenKey = "grazie-authenticate-jwt" | |
| ) | |
| var modelMap = map[string]OpenAIModel{ | |
| "gpt-4o": {Object: "model", OwnedBy: "openai", Profile: "openai-gpt-4o"}, | |
| "o1": {Object: "model", OwnedBy: "openai", Profile: "openai-o1"}, | |
| "o3": {Object: "model", OwnedBy: "openai", Profile: "openai-o3"}, | |
| "o3-mini": {Object: "model", OwnedBy: "openai", Profile: "openai-o3-mini"}, | |
| "o4-mini": {Object: "model", OwnedBy: "openai", Profile: "openai-o4-mini"}, | |
| "gpt4.1": {Object: "model", OwnedBy: "openai", Profile: "openai-gpt4.1"}, | |
| "gpt4.1-mini": {Object: "model", OwnedBy: "openai", Profile: "openai-gpt4.1-mini"}, | |
| "gpt4.1-nano": {Object: "model", OwnedBy: "openai", Profile: "openai-gpt4.1-nano"}, | |
| "gemini-pro-2.5": {Object: "model", OwnedBy: "google", Profile: "google-chat-gemini-pro-2.5"}, | |
| "gemini-flash-2.0": {Object: "model", OwnedBy: "google", Profile: "google-chat-gemini-flash-2.0"}, | |
| "gemini-flash-2.5": {Object: "model", OwnedBy: "google", Profile: "google-chat-gemini-flash-2.5"}, | |
| "claude-3.5-haiku": {Object: "model", OwnedBy: "anthropic", Profile: "anthropic-claude-3.5-haiku"}, | |
| "claude-3.5-sonnet": {Object: "model", OwnedBy: "anthropic", Profile: "anthropic-claude-3.5-sonnet"}, | |
| "claude-3.7-sonnet": {Object: "model", OwnedBy: "anthropic", Profile: "anthropic-claude-3.7-sonnet"}, | |
| "claude-4-sonnet": {Object: "model", OwnedBy: "anthropic", Profile: "anthropic-claude-4-sonnet"}, | |
| } | |
| type OpenAIModel struct { | |
| ID string `json:"id"` | |
| Object string `json:"object"` | |
| OwnedBy string `json:"owned_by"` | |
| Profile string `json:"profile"` | |
| } | |
| type OpenAIModelList struct { | |
| Object string `json:"object"` | |
| Data []OpenAIModel `json:"data"` | |
| } | |
| type MessageField struct { | |
| Type string `json:"type"` | |
| Content string `json:"content,omitempty"` | |
| } | |
| type JetbrainsRequest struct { | |
| Prompt string `json:"prompt"` | |
| Profile string `json:"profile"` | |
| Chat ChatField `json:"chat"` | |
| } | |
| type ChatField struct { | |
| MessageField []MessageField `json:"messages"` | |
| } | |
| func ChatGPTToJetbrainsAI(chatReq openai.ChatCompletionRequest) (*JetbrainsRequest, error) { | |
| messageFields, err := convertOpenAIMessagesToJetbrains(chatReq.Messages) | |
| if err != nil { | |
| return nil, fmt.Errorf("failed to convert messages: %w", err) | |
| } | |
| openaiModel, err := GetModelByName(chatReq.Model) | |
| if err != nil { | |
| return nil, fmt.Errorf("failed to get model: %w", err) | |
| } | |
| mReq := &JetbrainsRequest{ | |
| Prompt: PROMPT, | |
| Profile: openaiModel.Profile, | |
| Chat: ChatField{ | |
| MessageField: messageFields, | |
| }, | |
| } | |
| if jsonData, err := json.MarshalIndent(mReq, "", " "); err == nil { | |
| fmt.Printf("mReq JSON: %s\n", string(jsonData)) | |
| } | |
| return mReq, nil | |
| } | |
| func convertOpenAIMessagesToJetbrains(openaiMessages []openai.ChatCompletionMessage) ([]MessageField, error) { | |
| var messageField []MessageField | |
| for _, msg := range openaiMessages { | |
| if msg.Role == "system" { | |
| messageField = append(messageField, MessageField{ | |
| Type: "system_message", | |
| Content: msg.Content, | |
| }) | |
| } else if msg.Role == "user" { | |
| messageField = append(messageField, MessageField{ | |
| Type: "user_message", | |
| Content: msg.Content, | |
| }) | |
| } else if msg.Role == "assistant" { | |
| messageField = append(messageField, MessageField{ | |
| Type: "assistant_message", | |
| Content: msg.Content, | |
| }) | |
| } | |
| } | |
| return messageField, nil | |
| } | |
| func GetModelByName(modelName string) (OpenAIModel, error) { | |
| model, exists := modelMap[modelName] | |
| if !exists { | |
| return OpenAIModel{}, fmt.Errorf("model '%s' not found", modelName) | |
| } | |
| return model, nil | |
| } | |
| func GetSupportedModels() OpenAIModelList { | |
| var modelSlice []OpenAIModel | |
| for id, model := range modelMap { | |
| modelWithID := model | |
| modelWithID.ID = id | |
| modelSlice = append(modelSlice, modelWithID) | |
| } | |
| return OpenAIModelList{ | |
| Object: "list", | |
| Data: modelSlice, | |
| } | |
| } | |