diff --git a/src/main/java/ee/carlrobert/codegpt/settings/service/custom/CustomServiceFormTabbedPane.java b/src/main/java/ee/carlrobert/codegpt/settings/service/custom/CustomServiceFormTabbedPane.java index e6937bba..e732221c 100644 --- a/src/main/java/ee/carlrobert/codegpt/settings/service/custom/CustomServiceFormTabbedPane.java +++ b/src/main/java/ee/carlrobert/codegpt/settings/service/custom/CustomServiceFormTabbedPane.java @@ -26,6 +26,7 @@ public class CustomServiceFormTabbedPane extends JBTabbedPane { bodyTable = new JBTable( new DefaultTableModel(toArray(body), new Object[]{"Key", "Value"})); + bodyTable.setVisibleRowCount(6); setTabComponentInsets(JBUI.insetsTop(8)); addTab("Headers", createTablePanel(headersTable)); diff --git a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowPanel.java b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowPanel.java index 41b8327b..f268b821 100644 --- a/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowPanel.java +++ b/src/main/java/ee/carlrobert/codegpt/toolwindow/chat/ChatToolWindowPanel.java @@ -16,6 +16,7 @@ import com.intellij.openapi.ui.SimpleToolWindowPanel; import com.intellij.openapi.util.Disposer; import com.intellij.ui.components.ActionLink; import com.intellij.util.ui.JBUI; +import com.intellij.util.ui.JBUI.CurrentTheme.Link; import ee.carlrobert.codegpt.CodeGPTKeys; import ee.carlrobert.codegpt.actions.toolwindow.ClearChatWindowAction; import ee.carlrobert.codegpt.actions.toolwindow.CreateNewConversationAction; @@ -23,6 +24,7 @@ import ee.carlrobert.codegpt.actions.toolwindow.OpenInEditorAction; import ee.carlrobert.codegpt.conversations.ConversationService; import ee.carlrobert.codegpt.conversations.ConversationsState; import ee.carlrobert.codegpt.settings.GeneralSettings; +import ee.carlrobert.codegpt.settings.prompts.PersonaPromptDetailsState; import ee.carlrobert.codegpt.settings.prompts.PromptsConfigurable; import ee.carlrobert.codegpt.settings.prompts.PromptsSettings; import ee.carlrobert.codegpt.settings.service.ProviderChangeNotifier; @@ -164,16 +166,30 @@ public class ChatToolWindowPanel extends SimpleToolWindowPanel { this.project = project; } + private void showPromptsSettingsDialog() { + ShowSettingsUtil.getInstance() + .showSettingsDialog(project, PromptsConfigurable.class); + } + @Override @NotNull public JComponent createCustomComponent( @NotNull Presentation presentation, @NotNull String place) { - var link = new ActionLink(getSelectedPersonaName(), (e) -> { - ShowSettingsUtil.getInstance() - .showSettingsDialog(project, PromptsConfigurable.class); + var selectedPersona = getSelectedPersona(); + var personaName = selectedPersona.getName(); + if (personaName == null) { + personaName = "No persona selected"; + } + + var link = new ActionLink(personaName, (e) -> { + showPromptsSettingsDialog(); }); link.setExternalLinkIcon(); + if (selectedPersona.getDisabled()) { + link.setToolTipText("Persona is disabled"); + link.setForeground(JBUI.CurrentTheme.Label.disabledForeground()); + } link.setFont(JBUI.Fonts.smallFont()); link.setBorder(JBUI.Borders.empty(0, 4)); return link; @@ -183,19 +199,32 @@ public class ChatToolWindowPanel extends SimpleToolWindowPanel { public void updateCustomComponent( @NotNull JComponent component, @NotNull Presentation presentation) { - ((ActionLink) component).setText(getSelectedPersonaName()); + if (component instanceof ActionLink actionLink) { + var selectedPersona = getSelectedPersona(); + var personaName = selectedPersona.getName(); + if (personaName == null) { + personaName = "No persona selected"; + } + + if (selectedPersona.getDisabled()) { + actionLink.setText(personaName + " (disabled)"); + actionLink.setForeground(Link.Foreground.DISABLED); + } else { + actionLink.setText(personaName); + actionLink.setForeground(Link.Foreground.ENABLED); + } + } } @Override public void actionPerformed(@NotNull AnActionEvent e) { } - private String getSelectedPersonaName() { + private PersonaPromptDetailsState getSelectedPersona() { return ApplicationManager.getApplication().getService(PromptsSettings.class) .getState() .getPersonas() - .getSelectedPersona() - .getName(); + .getSelectedPersona(); } } -} +} \ No newline at end of file diff --git a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/ClaudeRequestFactory.kt b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/ClaudeRequestFactory.kt index 12a260f3..ffdc6c44 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/ClaudeRequestFactory.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/ClaudeRequestFactory.kt @@ -4,7 +4,6 @@ import com.intellij.openapi.components.service import ee.carlrobert.codegpt.completions.BaseRequestFactory import ee.carlrobert.codegpt.completions.ChatCompletionParameters import ee.carlrobert.codegpt.settings.configuration.ConfigurationSettings -import ee.carlrobert.codegpt.settings.persona.PersonaSettings import ee.carlrobert.codegpt.settings.prompts.PromptsSettings import ee.carlrobert.codegpt.settings.service.anthropic.AnthropicSettings import ee.carlrobert.llm.client.anthropic.completion.* @@ -17,7 +16,11 @@ class ClaudeRequestFactory : BaseRequestFactory() { model = service().state.model maxTokens = service().state.maxTokens isStream = true - system = PromptsSettings.getSelectedPersonaSystemPrompt() + + val selectedPersona = service().state.personas.selectedPersona + if (!selectedPersona.disabled) { + system = PromptsSettings.getSelectedPersonaSystemPrompt() + } messages = params.conversation.messages .filter { it.response != null && it.response.isNotEmpty() } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/GoogleRequestFactory.kt b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/GoogleRequestFactory.kt index c8fac458..2ca470d3 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/GoogleRequestFactory.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/GoogleRequestFactory.kt @@ -96,13 +96,16 @@ class GoogleRequestFactory : BaseRequestFactory() { when (params.conversationType) { ConversationType.DEFAULT -> { - messages.add( - GoogleCompletionContent( - "user", - listOf(PromptsSettings.getSelectedPersonaSystemPrompt()) + val selectedPersona = service().state.personas.selectedPersona + if (!selectedPersona.disabled) { + messages.add( + GoogleCompletionContent( + "user", + listOf(PromptsSettings.getSelectedPersonaSystemPrompt()) + ) ) - ) - messages.add(GoogleCompletionContent("model", listOf("Understood."))) + messages.add(GoogleCompletionContent("model", listOf("Understood."))) + } } ConversationType.FIX_COMPILE_ERRORS -> { diff --git a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/LlamaRequestFactory.kt b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/LlamaRequestFactory.kt index 53d8f0ab..6bffa3fc 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/LlamaRequestFactory.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/LlamaRequestFactory.kt @@ -16,10 +16,14 @@ class LlamaRequestFactory : BaseRequestFactory() { override fun createChatRequest(params: ChatCompletionParameters): LlamaCompletionRequest { val promptTemplate = getPromptTemplate() val systemPrompt = - if (params.conversationType == ConversationType.FIX_COMPILE_ERRORS) + if (params.conversationType == ConversationType.FIX_COMPILE_ERRORS) { service().state.coreActions.fixCompileErrors.instructions - else - PromptsSettings.getSelectedPersonaSystemPrompt() + } else { + service().state.personas.selectedPersona.let { + if (it.disabled) null else it.instructions + } + } + val prompt = promptTemplate.buildPrompt( systemPrompt, getPromptWithFilesContext(params), diff --git a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/OpenAIRequestFactory.kt b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/OpenAIRequestFactory.kt index 62db78bf..6a2983df 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/OpenAIRequestFactory.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/completions/factory/OpenAIRequestFactory.kt @@ -11,7 +11,6 @@ import ee.carlrobert.codegpt.settings.prompts.CoreActionsState import ee.carlrobert.codegpt.settings.prompts.PromptsSettings import ee.carlrobert.codegpt.settings.service.openai.OpenAISettings import ee.carlrobert.codegpt.util.file.FileUtil.getImageMediaType -import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionModel import ee.carlrobert.llm.client.openai.completion.OpenAIChatCompletionModel.* import ee.carlrobert.llm.client.openai.completion.request.* import java.io.IOException @@ -133,7 +132,7 @@ class OpenAIRequestFactory : CompletionRequestFactory { .sum() + getState().maxTokens val modelMaxTokens: Int try { - modelMaxTokens = OpenAIChatCompletionModel.findByCode(model).maxTokens + modelMaxTokens = findByCode(model).maxTokens if (totalUsage <= modelMaxTokens) { return messages @@ -158,14 +157,12 @@ class OpenAIRequestFactory : CompletionRequestFactory { val messages = mutableListOf() val role = if (isReasoningModel(model)) "user" else "system" - if (callParameters.conversationType == ConversationType.DEFAULT) { + val selectedPersona = service().state.personas.selectedPersona + if (callParameters.conversationType == ConversationType.DEFAULT && !selectedPersona.disabled) { val sessionPersonaDetails = callParameters.personaDetails if (sessionPersonaDetails == null) { messages.add( - OpenAIChatCompletionStandardMessage( - role, - PromptsSettings.getSelectedPersonaSystemPrompt() - ) + OpenAIChatCompletionStandardMessage(role, selectedPersona.instructions) ) } else { messages.add( diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/PromptsSettings.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/PromptsSettings.kt index 15e89834..fad4c194 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/PromptsSettings.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/PromptsSettings.kt @@ -196,6 +196,7 @@ class ChatActionPromptDetailsState : PromptDetailsState() { class PersonaPromptDetailsState : PromptDetailsState() { var id by property(1L) + var disabled by property(false) } @JvmRecord diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/PromptsForm.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/PromptsForm.kt index 520e40ae..acad6767 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/PromptsForm.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/PromptsForm.kt @@ -208,7 +208,8 @@ class PromptsForm { .all { (details, prompt) -> details.id == prompt.id && details.name == prompt.name && - details.instructions == prompt.instructions + details.instructions == prompt.instructions && + details.disabled == prompt.disabled } } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/PromptsFormUtil.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/PromptsFormUtil.kt index 597d4785..6a8b0dbf 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/PromptsFormUtil.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/PromptsFormUtil.kt @@ -39,6 +39,7 @@ object PromptsFormUtil { state.id = this.id state.name = this.name state.instructions = this.instructions + state.disabled = this.disabled return state } diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/details/FormDetails.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/details/FormDetails.kt index 5e05ee83..24a756db 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/details/FormDetails.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/details/FormDetails.kt @@ -61,11 +61,13 @@ data class PersonaPromptDetails( override var name: String?, override var instructions: String?, val id: Long, - var selected: AtomicBooleanProperty = AtomicBooleanProperty(false) + var selected: AtomicBooleanProperty = AtomicBooleanProperty(false), + var disabled: Boolean = false ) : FormPromptDetails() { constructor(state: PersonaPromptDetailsState) : this( name = state.name, instructions = state.instructions, - id = state.id + id = state.id, + disabled = state.disabled ) } \ No newline at end of file diff --git a/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/details/PersonasDetailsPanel.kt b/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/details/PersonasDetailsPanel.kt index 2cbae81c..ba0942df 100644 --- a/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/details/PersonasDetailsPanel.kt +++ b/src/main/kotlin/ee/carlrobert/codegpt/settings/prompts/form/details/PersonasDetailsPanel.kt @@ -5,10 +5,12 @@ import com.intellij.openapi.editor.event.DocumentEvent import com.intellij.openapi.editor.event.DocumentListener import com.intellij.openapi.observable.util.not import com.intellij.ui.CardLayoutPanel +import com.intellij.ui.components.JBCheckBox import com.intellij.ui.components.JBTextField import com.intellij.ui.dsl.builder.Align import com.intellij.ui.dsl.builder.TopGap import com.intellij.ui.dsl.builder.panel +import com.intellij.ui.dsl.builder.selected import com.intellij.ui.layout.ComponentPredicate import com.intellij.util.ui.components.BorderLayoutPanel import ee.carlrobert.codegpt.settings.prompts.PersonasState.Companion.DEFAULT_PERSONA_PROMPT @@ -95,6 +97,12 @@ class PersonasDetailsPanel(onSelected: (PersonaPromptDetails) -> Unit) : PromptD .align(Align.FILL) .onChanged { details.name = it.text } } + row { + checkBox("Disable persona") + .selected(details.disabled) + .comment("If checked, the selected persona will not be used when making chat queries. This is particularly useful when the model does not support system prompt.") + .onChanged { details.disabled = it.isSelected } + } row { button("Set as Default") { onSelected(details) diff --git a/src/main/resources/messages/codegpt.properties b/src/main/resources/messages/codegpt.properties index a66f0f52..884166ba 100644 --- a/src/main/resources/messages/codegpt.properties +++ b/src/main/resources/messages/codegpt.properties @@ -142,7 +142,7 @@ configurationConfigurable.section.codeCompletion.multiLineCompletions.descriptio configurationConfigurable.section.codeCompletion.postProcess.title=Enable tree-sitter post-processing configurationConfigurable.section.codeCompletion.postProcess.description=If checked, the completion will be post-processed using the tree-sitter parser. configurationConfigurable.section.codeCompletion.gitDiff.title=Enable git diff context -configurationConfigurable.section.codeCompletion.collectDependencyStructure.title=Collect the dependencies of the analyzed file. +configurationConfigurable.section.codeCompletion.collectDependencyStructure.title=Enable dependency analyzer configurationConfigurable.section.codeCompletion.collectDependencyStructure.description=Enabling the setting allows the plugin to collect the dependency structure, which increases the accuracy of the proposed data, but consumes more tokens per request. Currently, it is implemented only for the Kotlin language. configurationConfigurable.section.codeCompletion.gitDiff.description=If checked, the user's most recent unstaged git diff will be included when requesting completion. settingsConfigurable.service.llama.topK.label=Top K: