feat: remove model-conversation dependency

This commit is contained in:
Carl-Robert Linnupuu 2025-06-16 19:52:32 +02:00
parent 06e0484f8c
commit 465feafc9f
16 changed files with 32 additions and 302 deletions

View file

@ -42,7 +42,7 @@ public class OpenInEditorAction extends AnAction {
if (project != null && currentConversation != null) {
var dateTimeStamp = currentConversation.getUpdatedOn()
.format(DateTimeFormatter.ofPattern("yyyyMMddHHmm"));
var fileName = format("%s_%s.md", currentConversation.getModel(), dateTimeStamp);
var fileName = format("proxyai_conversation_%s.md", dateTimeStamp);
var fileContent = currentConversation
.getMessages()
.stream()

View file

@ -82,7 +82,6 @@ public class ChatCompletionEventListener implements CompletionEventListener<Stri
} else {
telemetryMessage
.property("conversationId", callParameters.getConversation().getId().toString())
.property("model", callParameters.getConversation().getModel())
.error(new RuntimeException(error.toString(), ex));
}
telemetryMessage.send();

View file

@ -69,7 +69,6 @@ public class ToolwindowChatCompletionRequestHandler {
private void sendInfo(ChatCompletionParameters callParameters) {
TelemetryAction.COMPLETION.createActionMessage()
.property("conversationId", callParameters.getConversation().getId().toString())
.property("model", callParameters.getConversation().getModel())
.property("service", GeneralSettings.getSelectedService().getCode().toLowerCase())
.send();
}

View file

@ -1,17 +1,17 @@
package ee.carlrobert.codegpt.conversations;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import ee.carlrobert.codegpt.conversations.message.Message;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@JsonIgnoreProperties(ignoreUnknown = true)
public class Conversation {
private UUID id;
private List<Message> messages = new ArrayList<>();
private String clientCode;
private String model;
private LocalDateTime createdOn;
private LocalDateTime updatedOn;
private boolean discardTokenLimit;
@ -32,26 +32,10 @@ public class Conversation {
this.messages = new ArrayList<>(messages);
}
public String getClientCode() {
return clientCode;
}
public void setClientCode(String clientCode) {
this.clientCode = clientCode;
}
public void addMessage(Message message) {
messages.add(message);
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public LocalDateTime getCreatedOn() {
return createdOn;
}

View file

@ -5,19 +5,9 @@ import com.intellij.openapi.components.Service;
import com.intellij.openapi.diagnostic.Logger;
import ee.carlrobert.codegpt.completions.ChatCompletionParameters;
import ee.carlrobert.codegpt.conversations.message.Message;
import ee.carlrobert.codegpt.settings.GeneralSettings;
import ee.carlrobert.codegpt.settings.service.ServiceType;
import ee.carlrobert.codegpt.settings.service.anthropic.AnthropicSettings;
import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTServiceSettings;
import ee.carlrobert.codegpt.settings.service.google.GoogleSettings;
import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings;
import ee.carlrobert.codegpt.settings.service.ollama.OllamaSettings;
import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.ListIterator;
import java.util.Optional;
import java.util.UUID;
import org.jetbrains.annotations.NotNull;
@ -37,32 +27,22 @@ public final class ConversationService {
}
public List<Conversation> getSortedConversations() {
return conversationState.getConversationsMapping()
.values()
return conversationState.conversations
.stream()
.flatMap(List::stream)
.sorted(Comparator.comparing(Conversation::getUpdatedOn).reversed())
.toList();
}
public Conversation createConversation(String clientCode) {
public Conversation createConversation() {
var conversation = new Conversation();
conversation.setId(UUID.randomUUID());
conversation.setClientCode(clientCode);
conversation.setCreatedOn(LocalDateTime.now());
conversation.setUpdatedOn(LocalDateTime.now());
conversation.setModel(getModelForSelectedService(GeneralSettings.getSelectedService()));
return conversation;
}
public void addConversation(Conversation conversation) {
var conversationsMapping = conversationState.getConversationsMapping();
var conversations = conversationsMapping.get(conversation.getClientCode());
if (conversations == null) {
conversations = new ArrayList<>();
}
conversations.add(conversation);
conversationsMapping.put(conversation.getClientCode(), conversations);
conversationState.conversations.add(conversation);
}
public void saveMessage(String response, ChatCompletionParameters callParameters) {
@ -85,62 +65,28 @@ public final class ConversationService {
public void saveMessage(@NotNull Conversation conversation, @NotNull Message message) {
conversation.setUpdatedOn(LocalDateTime.now());
var iterator = getIterator(conversation.getClientCode());
while (iterator.hasNext()) {
var next = iterator.next();
next.setMessages(
next.getMessages().stream().map(item -> {
if (item.getId() == message.getId()) {
return message;
}
return item;
}).toList());
if (next.getId().equals(conversation.getId())) {
iterator.set(conversation);
}
}
conversation.addMessage(message);
}
public void saveConversation(Conversation conversation) {
conversation.setUpdatedOn(LocalDateTime.now());
var iterator = getIterator(conversation.getClientCode());
while (iterator.hasNext()) {
var next = iterator.next();
if (next.getId().equals(conversation.getId())) {
iterator.set(conversation);
}
}
conversationState.setCurrentConversation(conversation);
}
public Conversation startConversation() {
var selectedService = GeneralSettings.getSelectedService();
if (selectedService == null) {
LOG.warn("Selected service is not defined, falling back to ProxyAI.");
selectedService = ServiceType.CODEGPT;
}
var completionCode = selectedService.getCompletionCode();
var conversation = createConversation(completionCode);
var conversation = createConversation();
conversationState.setCurrentConversation(conversation);
addConversation(conversation);
return conversation;
}
public void clearAll() {
conversationState.getConversationsMapping().clear();
conversationState.conversations.clear();
conversationState.setCurrentConversation(null);
}
public void deleteConversation(Conversation conversation) {
var iterator = getIterator(conversation.getClientCode());
while (iterator.hasNext()) {
var next = iterator.next();
if (next.getId().equals(conversation.getId())) {
iterator.remove();
break;
}
}
conversationState.conversations.removeIf(it -> it.getId() == conversation.getId());
}
public void deleteSelectedConversation() {
@ -171,12 +117,6 @@ public final class ConversationService {
return tryGetNextOrPreviousConversation(false);
}
private ListIterator<Conversation> getIterator(String clientCode) {
return conversationState.getConversationsMapping()
.get(clientCode)
.listIterator();
}
private Optional<Conversation> tryGetNextOrPreviousConversation(boolean isPrevious) {
var currentConversation = ConversationsState.getCurrentConversation();
if (currentConversation != null) {
@ -194,29 +134,4 @@ public final class ConversationService {
}
return Optional.empty();
}
public String getModelForSelectedService(ServiceType serviceType) {
var application = ApplicationManager.getApplication();
return switch (serviceType) {
case CODEGPT -> application.getService(CodeGPTServiceSettings.class)
.getState()
.getChatCompletionSettings()
.getModel();
case OPENAI -> OpenAISettings.getCurrentState().getModel();
case CUSTOM_OPENAI -> "CustomService";
case ANTHROPIC -> AnthropicSettings.getCurrentState().getModel();
case LLAMA_CPP -> {
var llamaSettings = LlamaSettings.getCurrentState();
yield llamaSettings.isUseCustomModel()
? llamaSettings.getCustomLlamaModelPath()
: llamaSettings.getHuggingFaceModel().getCode();
}
case OLLAMA -> application.getService(OllamaSettings.class)
.getState()
.getModel();
case GOOGLE -> application.getService(GoogleSettings.class)
.getState()
.getModel();
};
}
}

View file

@ -8,8 +8,10 @@ import com.intellij.util.xmlb.XmlSerializerUtil;
import com.intellij.util.xmlb.annotations.OptionTag;
import ee.carlrobert.codegpt.conversations.converter.ConversationConverter;
import ee.carlrobert.codegpt.conversations.converter.ConversationsConverter;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@ -18,12 +20,15 @@ import org.jetbrains.annotations.Nullable;
storages = @Storage("ChatGPTConversations_170.xml"))
public class ConversationsState implements PersistentStateComponent<ConversationsState> {
@Deprecated
@OptionTag(converter = ConversationsConverter.class)
public ConversationsContainer conversationsContainer = new ConversationsContainer();
@OptionTag(converter = ConversationConverter.class)
public Conversation currentConversation;
public List<Conversation> conversations = new ArrayList<>();
public boolean discardAllTokenLimits;
public static ConversationsState getInstance() {
@ -39,6 +44,11 @@ public class ConversationsState implements PersistentStateComponent<Conversation
@Override
public void loadState(@NotNull ConversationsState state) {
XmlSerializerUtil.copyBean(state, this);
conversationsContainer.getConversationsMapping().values().stream()
.flatMap(Collection::stream)
.sorted(Comparator.comparing(Conversation::getUpdatedOn).reversed())
.forEachOrdered(it -> conversations.add(it));
}
public void discardAllTokenLimits() {
@ -52,8 +62,4 @@ public class ConversationsState implements PersistentStateComponent<Conversation
public static @Nullable Conversation getCurrentConversation() {
return getInstance().currentConversation;
}
public Map<String, List<Conversation>> getConversationsMapping() {
return conversationsContainer.getConversationsMapping();
}
}

View file

@ -4,20 +4,14 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import ee.carlrobert.codegpt.CodeGPTKeys;
import ee.carlrobert.codegpt.completions.HuggingFaceModel;
import ee.carlrobert.codegpt.completions.llama.LlamaModel;
import ee.carlrobert.codegpt.conversations.Conversation;
import ee.carlrobert.codegpt.settings.service.ProviderChangeNotifier;
import ee.carlrobert.codegpt.settings.service.ServiceType;
import ee.carlrobert.codegpt.settings.service.anthropic.AnthropicSettings;
import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTService;
import ee.carlrobert.codegpt.settings.service.codegpt.CodeGPTServiceSettings;
import ee.carlrobert.codegpt.settings.service.google.GoogleSettings;
import ee.carlrobert.codegpt.settings.service.llama.LlamaSettings;
import ee.carlrobert.codegpt.settings.service.ollama.OllamaSettings;
import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings;
import ee.carlrobert.codegpt.util.ApplicationUtil;
import org.jetbrains.annotations.NotNull;
@State(name = "CodeGPT_GeneralSettings_270", storages = @Storage("CodeGPT_GeneralSettings_270.xml"))
@ -52,56 +46,6 @@ public class GeneralSettings implements PersistentStateComponent<GeneralSettings
return getSelectedService() == serviceType;
}
public void sync(Conversation conversation) {
var project = ApplicationUtil.findCurrentProject();
var provider = ServiceType.fromClientCode(conversation.getClientCode());
switch (provider) {
case OPENAI:
OpenAISettings.getCurrentState().setModel(conversation.getModel());
break;
case LLAMA_CPP:
var llamaSettings = LlamaSettings.getCurrentState();
try {
var huggingFaceModel = HuggingFaceModel.valueOf(conversation.getModel());
llamaSettings.setHuggingFaceModel(huggingFaceModel);
llamaSettings.setUseCustomModel(false);
} catch (IllegalArgumentException ignore) {
llamaSettings.setCustomLlamaModelPath(conversation.getModel());
llamaSettings.setUseCustomModel(true);
}
break;
case CODEGPT:
ApplicationManager.getApplication().getService(CodeGPTServiceSettings.class).getState()
.getChatCompletionSettings().setModel(conversation.getModel());
var existingUserDetails = CodeGPTKeys.CODEGPT_USER_DETAILS.get(project);
if (project != null && existingUserDetails == null) {
project.getService(CodeGPTService.class).syncUserDetailsAsync();
}
break;
case ANTHROPIC:
ApplicationManager.getApplication().getService(AnthropicSettings.class).getState()
.setModel(conversation.getModel());
break;
case GOOGLE:
ApplicationManager.getApplication().getService(GoogleSettings.class).getState()
.setModel(conversation.getModel());
break;
case OLLAMA:
ApplicationManager.getApplication().getService(OllamaSettings.class).getState()
.setModel(conversation.getModel());
break;
default:
break;
}
state.setSelectedService(provider);
if (project != null) {
project.getMessageBus()
.syncPublisher(ProviderChangeNotifier.getTOPIC())
.providerChanged(provider);
}
}
public String getModel() {
switch (state.getSelectedService()) {
case CODEGPT:

View file

@ -105,7 +105,6 @@ public class ChatToolWindowTabbedPane extends JBTabbedPane {
var conversation = toolWindowPanel.getConversation();
if (conversation != null) {
ConversationsState.getInstance().setCurrentConversation(conversation);
GeneralSettings.getInstance().sync(conversation);
}
}
}

View file

@ -106,7 +106,6 @@ abstract class ToolWindowCompletionResponseEventListener implements
if (answer == OK) {
TelemetryAction.IDE_ACTION.createActionMessage()
.property("action", "DISCARD_TOKEN_LIMIT")
.property("model", conversation.getModel())
.send();
ConversationService.getInstance().discardTokenLimits(conversation);

View file

@ -8,10 +8,8 @@ import com.intellij.util.ui.JBUI;
import ee.carlrobert.codegpt.actions.toolwindow.DeleteConversationAction;
import ee.carlrobert.codegpt.conversations.Conversation;
import ee.carlrobert.codegpt.conversations.ConversationsState;
import ee.carlrobert.codegpt.settings.GeneralSettings;
import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager;
import ee.carlrobert.codegpt.ui.IconActionButton;
import ee.carlrobert.codegpt.ui.ModelIconLabel;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.GridBagConstraints;
@ -42,7 +40,6 @@ class ConversationPanel extends JPanel {
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
GeneralSettings.getInstance().sync(conversation);
toolWindowContentManager.displayConversation(conversation);
}
});
@ -92,11 +89,6 @@ class ConversationPanel extends JPanel {
var bottomPanel = new JPanel(new BorderLayout());
bottomPanel.add(new JLabel(conversation.getUpdatedOn()
.format(DateTimeFormatter.ofPattern("M/d/yyyy, h:mm:ss a"))), BorderLayout.WEST);
if (conversation.getModel() != null) {
bottomPanel.add(
new ModelIconLabel(conversation.getClientCode(), conversation.getModel()),
BorderLayout.EAST);
}
var textPanel = new JPanel(new BorderLayout());
textPanel.add(headerPanel, BorderLayout.NORTH);