mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-19 16:28:46 +00:00
feat: add project-based chat history filtering
This commit is contained in:
parent
bf48a90003
commit
339a581181
16 changed files with 316 additions and 44 deletions
|
|
@ -16,6 +16,7 @@ public class Conversation {
|
|||
private LocalDateTime createdOn;
|
||||
private LocalDateTime updatedOn;
|
||||
private boolean discardTokenLimit;
|
||||
private String projectPath;
|
||||
|
||||
public Conversation() {
|
||||
this.messages = new ArrayList<>();
|
||||
|
|
@ -82,4 +83,12 @@ public class Conversation {
|
|||
.filter(message -> !message.getId().equals(messageId))
|
||||
.toList());
|
||||
}
|
||||
|
||||
public String getProjectPath() {
|
||||
return projectPath;
|
||||
}
|
||||
|
||||
public void setProjectPath(String projectPath) {
|
||||
this.projectPath = projectPath;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package ee.carlrobert.codegpt.conversations;
|
|||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.components.Service;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import ee.carlrobert.codegpt.completions.ChatCompletionParameters;
|
||||
import ee.carlrobert.codegpt.conversations.message.Message;
|
||||
import java.time.LocalDateTime;
|
||||
|
|
@ -74,8 +75,13 @@ public final class ConversationService {
|
|||
conversationState.setCurrentConversation(conversation);
|
||||
}
|
||||
|
||||
public Conversation startConversation() {
|
||||
public Conversation startConversation(Project project) {
|
||||
return startConversation(project != null ? project.getBasePath() : null);
|
||||
}
|
||||
|
||||
private Conversation startConversation(String projectPath) {
|
||||
var conversation = createConversation();
|
||||
conversation.setProjectPath(projectPath);
|
||||
conversationState.setCurrentConversation(conversation);
|
||||
addConversation(conversation);
|
||||
return conversation;
|
||||
|
|
|
|||
|
|
@ -78,7 +78,7 @@ public final class ChatToolWindowContentManager {
|
|||
.map(item -> {
|
||||
var panel = new ChatToolWindowTabPanel(
|
||||
project,
|
||||
ConversationService.getInstance().startConversation());
|
||||
ConversationService.getInstance().startConversation(project));
|
||||
item.addNewTab(panel);
|
||||
return panel;
|
||||
})
|
||||
|
|
@ -117,7 +117,7 @@ public final class ChatToolWindowContentManager {
|
|||
tabbedPane.clearAll();
|
||||
tabbedPane.addNewTab(new ChatToolWindowTabPanel(
|
||||
project,
|
||||
ConversationService.getInstance().startConversation()));
|
||||
ConversationService.getInstance().startConversation(project)));
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -45,11 +45,13 @@ public class ChatToolWindowPanel extends SimpleToolWindowPanel {
|
|||
private final ToolWindowFooterNotification imageFileAttachmentNotification;
|
||||
private final ActionLink upgradePlanLink;
|
||||
private final ChatToolWindowTabbedPane tabbedPane;
|
||||
private final Project project;
|
||||
|
||||
public ChatToolWindowPanel(
|
||||
@NotNull Project project,
|
||||
@NotNull Disposable parentDisposable) {
|
||||
super(true);
|
||||
this.project = project;
|
||||
imageFileAttachmentNotification = new ToolWindowFooterNotification(() ->
|
||||
project.putUserData(CodeGPTKeys.IMAGE_ATTACHMENT_FILE_PATH, ""));
|
||||
upgradePlanLink = new ActionLink("Upgrade your plan", event -> {
|
||||
|
|
@ -72,7 +74,7 @@ public class ChatToolWindowPanel extends SimpleToolWindowPanel {
|
|||
private Conversation getConversation() {
|
||||
var conversation = ConversationsState.getCurrentConversation();
|
||||
if (conversation == null) {
|
||||
return ConversationService.getInstance().startConversation();
|
||||
return ConversationService.getInstance().startConversation(project);
|
||||
}
|
||||
return conversation;
|
||||
}
|
||||
|
|
@ -118,7 +120,7 @@ public class ChatToolWindowPanel extends SimpleToolWindowPanel {
|
|||
Runnable onAddNewTab = () -> {
|
||||
tabbedPane.addNewTab(new ChatToolWindowTabPanel(
|
||||
project,
|
||||
ConversationService.getInstance().startConversation()));
|
||||
ConversationService.getInstance().startConversation(project)));
|
||||
repaint();
|
||||
revalidate();
|
||||
};
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ public class ChatToolWindowTabbedPane extends JBTabbedPane {
|
|||
removeTabAt(getSelectedIndex());
|
||||
addNewTab(new ChatToolWindowTabPanel(
|
||||
project,
|
||||
ConversationService.getInstance().startConversation()));
|
||||
ConversationService.getInstance().startConversation(project)));
|
||||
repaint();
|
||||
revalidate();
|
||||
});
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.history
|
||||
|
||||
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||
import com.intellij.openapi.actionSystem.AnAction
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||
import com.intellij.openapi.util.Key
|
||||
import javax.swing.Icon
|
||||
|
||||
abstract class BaseFilterAction(
|
||||
text: String,
|
||||
description: String? = null,
|
||||
icon: Icon? = null
|
||||
) : AnAction(text, description, icon) {
|
||||
|
||||
companion object {
|
||||
val KEY: Key<Boolean> = Key.create("SELECTED_STATE")
|
||||
}
|
||||
|
||||
override fun getActionUpdateThread(): ActionUpdateThread {
|
||||
return ActionUpdateThread.BGT
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
e.presentation.putClientProperty(KEY, isSelected())
|
||||
}
|
||||
|
||||
abstract fun isSelected(): Boolean
|
||||
}
|
||||
|
|
@ -10,6 +10,7 @@ import com.intellij.util.ui.UIUtil
|
|||
import com.intellij.util.ui.components.BorderLayoutPanel
|
||||
import ee.carlrobert.codegpt.CodeGPTBundle
|
||||
import ee.carlrobert.codegpt.conversations.Conversation
|
||||
import ee.carlrobert.codegpt.util.ProjectPathUtils
|
||||
import java.awt.Color
|
||||
import java.awt.Cursor
|
||||
import java.awt.Dimension
|
||||
|
|
@ -195,7 +196,15 @@ class ChatHistoryItemPanel(
|
|||
private fun createMetadataPanel(): JPanel {
|
||||
return panel {
|
||||
row {
|
||||
label(formatDate())
|
||||
val dateText = formatDate()
|
||||
val projectName = ProjectPathUtils.extractProjectNameTruncated(conversation.projectPath)
|
||||
val metadataText = if (projectName != null) {
|
||||
"$dateText • [$projectName]"
|
||||
} else {
|
||||
dateText
|
||||
}
|
||||
|
||||
label(metadataText)
|
||||
.applyToComponent {
|
||||
font = JBFont.regular().deriveFont(11f)
|
||||
foreground = getMetadataColor()
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ import ee.carlrobert.codegpt.conversations.Conversation
|
|||
import ee.carlrobert.codegpt.conversations.ConversationService
|
||||
import ee.carlrobert.codegpt.conversations.ConversationsState
|
||||
import ee.carlrobert.codegpt.toolwindow.chat.ChatToolWindowContentManager
|
||||
import ee.carlrobert.codegpt.util.ProjectPathUtils
|
||||
import javax.swing.JOptionPane
|
||||
import javax.swing.JPanel
|
||||
import javax.swing.SwingUtilities
|
||||
|
|
@ -41,6 +42,7 @@ class ChatHistoryToolWindow(private val project: Project) : BorderLayoutPanel()
|
|||
private val searchField = SearchTextField()
|
||||
private var allConversations = mutableListOf<Conversation>()
|
||||
private var sortOption = SortOption.UPDATED_DATE_DESC
|
||||
private var projectFilter: ProjectFilterState = ProjectFilterState.AllProjects
|
||||
private val statusLabel = JBLabel().apply {
|
||||
font = JBFont.small()
|
||||
foreground = UIUtil.getContextHelpForeground()
|
||||
|
|
@ -49,6 +51,13 @@ class ChatHistoryToolWindow(private val project: Project) : BorderLayoutPanel()
|
|||
private var lastSearchText = ""
|
||||
private var lastFilteredConversations: List<Conversation>? = null
|
||||
private var isDataLoaded = false
|
||||
private var projectInfoCache: Map<String, ProjectInfo> = emptyMap()
|
||||
|
||||
data class ProjectInfo(
|
||||
val path: String,
|
||||
val name: String,
|
||||
val conversationCount: Int
|
||||
)
|
||||
|
||||
enum class SortOption(val propertyKey: String) {
|
||||
UPDATED_DATE_DESC("conversation.sortOption.recentlyUpdated"),
|
||||
|
|
@ -62,6 +71,32 @@ class ChatHistoryToolWindow(private val project: Project) : BorderLayoutPanel()
|
|||
get() = CodeGPTBundle.get(propertyKey)
|
||||
}
|
||||
|
||||
sealed class ProjectFilterState {
|
||||
object AllProjects : ProjectFilterState()
|
||||
object CurrentProjectOnly : ProjectFilterState()
|
||||
data class SelectedProjects(val projectPaths: Set<String>) : ProjectFilterState()
|
||||
|
||||
fun matches(conversationProjectPath: String?, currentProjectPath: String?): Boolean {
|
||||
return when (this) {
|
||||
is AllProjects -> true
|
||||
is CurrentProjectOnly -> conversationProjectPath == currentProjectPath
|
||||
is SelectedProjects -> projectPaths.contains(conversationProjectPath)
|
||||
}
|
||||
}
|
||||
|
||||
fun getDisplayText(): String {
|
||||
return when (this) {
|
||||
is AllProjects -> "All Projects"
|
||||
is CurrentProjectOnly -> "Current Project Only"
|
||||
is SelectedProjects -> when (projectPaths.size) {
|
||||
0 -> "No Projects"
|
||||
1 -> "1 Project Selected"
|
||||
else -> "${projectPaths.size} Projects Selected"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
setupUI()
|
||||
loadConversationsAsync()
|
||||
|
|
@ -154,14 +189,22 @@ class ChatHistoryToolWindow(private val project: Project) : BorderLayoutPanel()
|
|||
}
|
||||
|
||||
private fun filterConversations(searchText: String): List<Conversation> {
|
||||
val projectFiltered = allConversations.filter { conversation ->
|
||||
projectFilter.matches(conversation.projectPath, project.basePath)
|
||||
}
|
||||
|
||||
return if (searchText.isBlank()) {
|
||||
lastSearchText = ""
|
||||
lastFilteredConversations = null
|
||||
allConversations
|
||||
projectFiltered
|
||||
} else if (searchText == lastSearchText && lastFilteredConversations != null) {
|
||||
lastFilteredConversations!!
|
||||
lastFilteredConversations!!.filter { conversation ->
|
||||
projectFiltered.contains(conversation)
|
||||
}
|
||||
} else {
|
||||
val startList = getOptimizedSearchStartList(searchText)
|
||||
val startList = getOptimizedSearchStartList(searchText).filter { conversation ->
|
||||
projectFiltered.contains(conversation)
|
||||
}
|
||||
val filtered = startList.filter { conversation ->
|
||||
matchesSearchText(conversation, searchText)
|
||||
}
|
||||
|
|
@ -247,6 +290,105 @@ class ChatHistoryToolWindow(private val project: Project) : BorderLayoutPanel()
|
|||
return sortAction
|
||||
}
|
||||
|
||||
private fun createProjectFilterAction(): AnAction {
|
||||
return object : AnAction(
|
||||
projectFilter.getDisplayText(),
|
||||
"Filter conversations by project",
|
||||
AllIcons.General.Filter
|
||||
) {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
val actionGroup = DefaultActionGroup().apply {
|
||||
add(object : BaseFilterAction("All Projects", null, AllIcons.General.Filter) {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
projectFilter = ProjectFilterState.AllProjects
|
||||
sortAndFilterConversations()
|
||||
}
|
||||
|
||||
override fun isSelected(): Boolean {
|
||||
return projectFilter is ProjectFilterState.AllProjects
|
||||
}
|
||||
})
|
||||
|
||||
add(object : BaseFilterAction("Current Project Only", null, null) {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
projectFilter = ProjectFilterState.CurrentProjectOnly
|
||||
sortAndFilterConversations()
|
||||
}
|
||||
|
||||
override fun isSelected(): Boolean {
|
||||
return projectFilter is ProjectFilterState.CurrentProjectOnly
|
||||
}
|
||||
})
|
||||
|
||||
addSeparator("Available Projects")
|
||||
|
||||
val projects = getProjectsWithConversations()
|
||||
if (projects.isNotEmpty()) {
|
||||
projects.forEach { projectInfo ->
|
||||
val displayName =
|
||||
"${projectInfo.name} (${projectInfo.conversationCount})"
|
||||
val isCurrentProject = projectInfo.path == project.basePath
|
||||
val icon = if (isCurrentProject) AllIcons.Nodes.HomeFolder else null
|
||||
|
||||
add(object : BaseFilterAction(displayName, projectInfo.path, icon) {
|
||||
override fun actionPerformed(e: AnActionEvent) {
|
||||
projectFilter =
|
||||
ProjectFilterState.SelectedProjects(setOf(projectInfo.path))
|
||||
sortAndFilterConversations()
|
||||
}
|
||||
|
||||
override fun isSelected(): Boolean {
|
||||
return when (val filter = projectFilter) {
|
||||
is ProjectFilterState.SelectedProjects -> filter.projectPaths.contains(
|
||||
projectInfo.path
|
||||
)
|
||||
is ProjectFilterState.CurrentProjectOnly -> isCurrentProject
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
} else {
|
||||
add(object : AnAction("No projects with conversations", null, null) {
|
||||
override fun actionPerformed(e: AnActionEvent) {}
|
||||
override fun update(e: AnActionEvent) {
|
||||
e.presentation.isEnabled = false
|
||||
}
|
||||
|
||||
override fun getActionUpdateThread(): ActionUpdateThread {
|
||||
return ActionUpdateThread.BGT
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
val popup = JBPopupFactory.getInstance()
|
||||
.createActionGroupPopup(
|
||||
"Filter by Project",
|
||||
actionGroup,
|
||||
e.dataContext,
|
||||
JBPopupFactory.ActionSelectionAid.SPEEDSEARCH,
|
||||
true
|
||||
)
|
||||
|
||||
val component = e.inputEvent?.component
|
||||
if (component != null) {
|
||||
popup.showUnderneathOf(component)
|
||||
} else {
|
||||
popup.showInBestPositionFor(e.dataContext)
|
||||
}
|
||||
}
|
||||
|
||||
override fun update(e: AnActionEvent) {
|
||||
e.presentation.text = projectFilter.getDisplayText()
|
||||
}
|
||||
|
||||
override fun getActionUpdateThread(): ActionUpdateThread {
|
||||
return ActionUpdateThread.BGT
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun setupListeners() {
|
||||
var searchTimer: Timer? = null
|
||||
searchField.addDocumentListener(object : DocumentAdapter() {
|
||||
|
|
@ -282,6 +424,7 @@ class ChatHistoryToolWindow(private val project: Project) : BorderLayoutPanel()
|
|||
}
|
||||
})
|
||||
add(createSortAction())
|
||||
add(createProjectFilterAction())
|
||||
addSeparator()
|
||||
add(DeleteAllConversationsAction { refresh() })
|
||||
}
|
||||
|
|
@ -306,6 +449,7 @@ class ChatHistoryToolWindow(private val project: Project) : BorderLayoutPanel()
|
|||
.toMutableList()
|
||||
SwingUtilities.invokeLater {
|
||||
allConversations = conversations
|
||||
projectInfoCache = discoverProjects(conversations)
|
||||
lastSearchText = ""
|
||||
lastFilteredConversations = null
|
||||
isDataLoaded = true
|
||||
|
|
@ -345,11 +489,44 @@ class ChatHistoryToolWindow(private val project: Project) : BorderLayoutPanel()
|
|||
|
||||
private fun matchesSearchText(conversation: Conversation, searchText: String): Boolean {
|
||||
val searchLower = searchText.lowercase()
|
||||
return conversation.title?.lowercase()?.contains(searchLower) == true ||
|
||||
conversation.messages.take(MAX_MESSAGES_TO_SEARCH).any { message ->
|
||||
message.prompt?.lowercase()?.contains(searchLower) == true ||
|
||||
message.response?.lowercase()?.contains(searchLower) == true
|
||||
|
||||
if (conversation.title?.lowercase()?.contains(searchLower) == true) {
|
||||
return true
|
||||
}
|
||||
|
||||
conversation.projectPath?.let { path ->
|
||||
val projectName = ProjectPathUtils.extractProjectName(path)?.lowercase()
|
||||
if (projectName?.contains(searchLower) == true) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return conversation.messages.take(MAX_MESSAGES_TO_SEARCH).any { message ->
|
||||
message.prompt?.lowercase()?.contains(searchLower) == true ||
|
||||
message.response?.lowercase()?.contains(searchLower) == true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun discoverProjects(conversations: List<Conversation>): Map<String, ProjectInfo> {
|
||||
return conversations
|
||||
.mapNotNull { conversation ->
|
||||
conversation.projectPath?.let { path ->
|
||||
path to (ProjectPathUtils.extractProjectName(path) ?: path)
|
||||
}
|
||||
}
|
||||
.groupBy({ it.first }, { it.second })
|
||||
.mapValues { (path, names) ->
|
||||
ProjectInfo(
|
||||
path = path,
|
||||
name = names.firstOrNull() ?: path,
|
||||
conversationCount = conversations.count { it.projectPath == path }
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getProjectsWithConversations(): List<ProjectInfo> {
|
||||
return projectInfoCache.values.sortedByDescending { it.conversationCount }
|
||||
}
|
||||
|
||||
private fun updateList(conversations: List<Conversation>) {
|
||||
|
|
@ -366,6 +543,20 @@ class ChatHistoryToolWindow(private val project: Project) : BorderLayoutPanel()
|
|||
append(getConversationCountMessage(conversations, searchText))
|
||||
append(" • ")
|
||||
append(CodeGPTBundle.get("conversation.status.sortedBy", sortOption.displayName))
|
||||
|
||||
when (projectFilter) {
|
||||
is ProjectFilterState.CurrentProjectOnly -> {
|
||||
append(" • ")
|
||||
append("Current project only")
|
||||
}
|
||||
|
||||
is ProjectFilterState.SelectedProjects -> {
|
||||
append(" • ")
|
||||
append(projectFilter.getDisplayText())
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
package ee.carlrobert.codegpt.util
|
||||
|
||||
object ProjectPathUtils {
|
||||
private const val PROJECT_NAME_MAX_LENGTH = 30
|
||||
|
||||
fun extractProjectName(projectPath: String?): String? {
|
||||
if (projectPath.isNullOrEmpty()) return null
|
||||
|
||||
val separators = listOf('/', '\\')
|
||||
val lastSeparatorIndex = separators.maxOfOrNull { projectPath.lastIndexOf(it) } ?: -1
|
||||
|
||||
return if (lastSeparatorIndex >= 0 && lastSeparatorIndex < projectPath.length - 1) {
|
||||
projectPath.substring(lastSeparatorIndex + 1)
|
||||
} else {
|
||||
projectPath
|
||||
}
|
||||
}
|
||||
|
||||
fun extractProjectNameTruncated(projectPath: String?): String? {
|
||||
val projectName = extractProjectName(projectPath) ?: return null
|
||||
|
||||
return if (projectName.length > PROJECT_NAME_MAX_LENGTH) {
|
||||
projectName.substring(0, PROJECT_NAME_MAX_LENGTH - 3) + "..."
|
||||
} else {
|
||||
projectName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -22,7 +22,7 @@ class CompletionRequestProviderTest : IntegrationTest() {
|
|||
instructions = "TEST_SYSTEM_PROMPT"
|
||||
}
|
||||
service<PromptsSettings>().state.personas.selectedPersona = customPersona
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val firstMessage = createDummyMessage(500)
|
||||
val secondMessage = createDummyMessage(250)
|
||||
conversation.addMessage(firstMessage)
|
||||
|
|
@ -53,7 +53,7 @@ class CompletionRequestProviderTest : IntegrationTest() {
|
|||
instructions = "TEST_SYSTEM_PROMPT"
|
||||
}
|
||||
service<PromptsSettings>().state.personas.selectedPersona = customPersona
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val firstMessage = createDummyMessage("FIRST_TEST_PROMPT", 500)
|
||||
val secondMessage = createDummyMessage("SECOND_TEST_PROMPT", 250)
|
||||
conversation.addMessage(firstMessage)
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package ee.carlrobert.codegpt.completions
|
||||
|
||||
import com.intellij.openapi.components.service
|
||||
import ee.carlrobert.codegpt.completions.HuggingFaceModel
|
||||
import ee.carlrobert.codegpt.completions.llama.PromptTemplate.LLAMA
|
||||
import ee.carlrobert.codegpt.conversations.ConversationService
|
||||
import ee.carlrobert.codegpt.conversations.message.Message
|
||||
|
|
@ -27,7 +26,7 @@ class DefaultToolwindowChatCompletionRequestHandlerTest : IntegrationTest() {
|
|||
}
|
||||
service<PromptsSettings>().state.personas.selectedPersona = customPersona
|
||||
val message = Message("TEST_PROMPT")
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
expectOpenAI(StreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path).isEqualTo("/v1/chat/completions")
|
||||
assertThat(request.method).isEqualTo("POST")
|
||||
|
|
@ -72,7 +71,7 @@ class DefaultToolwindowChatCompletionRequestHandlerTest : IntegrationTest() {
|
|||
}
|
||||
service<PromptsSettings>().state.personas.selectedPersona = customPersona
|
||||
val message = Message("TEST_PROMPT")
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
conversation.addMessage(Message("Ping", "Pong"))
|
||||
expectLlama(StreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path).isEqualTo("/completion")
|
||||
|
|
@ -118,7 +117,7 @@ class DefaultToolwindowChatCompletionRequestHandlerTest : IntegrationTest() {
|
|||
}
|
||||
service<PromptsSettings>().state.personas.selectedPersona = customPersona
|
||||
val message = Message("TEST_PROMPT")
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
expectOllama(NdJsonStreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path).isEqualTo("/v1/chat/completions")
|
||||
assertThat(request.method).isEqualTo("POST")
|
||||
|
|
@ -162,7 +161,7 @@ class DefaultToolwindowChatCompletionRequestHandlerTest : IntegrationTest() {
|
|||
}
|
||||
service<PromptsSettings>().state.personas.selectedPersona = customPersona
|
||||
val message = Message("TEST_PROMPT")
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
expectGoogle(StreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path).isEqualTo("/v1/models/gemini-2.0-flash:streamGenerateContent")
|
||||
assertThat(request.method).isEqualTo("POST")
|
||||
|
|
@ -208,7 +207,7 @@ class DefaultToolwindowChatCompletionRequestHandlerTest : IntegrationTest() {
|
|||
}
|
||||
service<PromptsSettings>().state.personas.selectedPersona = customPersona
|
||||
val message = Message("TEST_PROMPT")
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
expectCodeGPT(StreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path).isEqualTo("/v1/chat/completions")
|
||||
assertThat(request.method).isEqualTo("POST")
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ class OpenAIRequestFactoryIntegrationTest : IntegrationTest() {
|
|||
fun testDefaultPersonaUsesEditModePromptWhenEnabled() {
|
||||
useOpenAIService(OpenAIChatCompletionModel.GPT_4_O.code)
|
||||
service<PromptsSettings>().state.personas.selectedPersona = PersonasState.DEFAULT_PERSONA
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val message = Message("Please refactor this code")
|
||||
val callParameters = ChatCompletionParameters
|
||||
.builder(conversation, message)
|
||||
|
|
@ -120,7 +120,7 @@ class OpenAIRequestFactoryIntegrationTest : IntegrationTest() {
|
|||
fun testDefaultPersonaIsFilteredInAskMode() {
|
||||
useOpenAIService(OpenAIChatCompletionModel.GPT_4_O.code)
|
||||
service<PromptsSettings>().state.personas.selectedPersona = PersonasState.DEFAULT_PERSONA
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val message = Message("Please refactor this code")
|
||||
val callParameters = ChatCompletionParameters
|
||||
.builder(conversation, message)
|
||||
|
|
@ -239,7 +239,7 @@ class OpenAIRequestFactoryIntegrationTest : IntegrationTest() {
|
|||
instructions = personaPromptWithSearchReplace
|
||||
}
|
||||
service<PromptsSettings>().state.personas.selectedPersona = customPersona
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val message = Message("Please refactor this code")
|
||||
val callParameters = ChatCompletionParameters
|
||||
.builder(conversation, message)
|
||||
|
|
@ -282,7 +282,7 @@ class OpenAIRequestFactoryIntegrationTest : IntegrationTest() {
|
|||
""".trimIndent()
|
||||
service<PromptsSettings>().state.personas.selectedPersona.instructions =
|
||||
personaPromptWithSearchReplace
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val message = Message("Please refactor this code")
|
||||
val callParameters = ChatCompletionParameters
|
||||
.builder(conversation, message)
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import org.assertj.core.api.Assertions.assertThat
|
|||
class ConversationsStateTest : BasePlatformTestCase() {
|
||||
|
||||
fun testStartNewDefaultConversation() {
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
|
||||
assertThat(conversation).isEqualTo(ConversationsState.getCurrentConversation())
|
||||
}
|
||||
|
|
@ -35,8 +35,8 @@ class ConversationsStateTest : BasePlatformTestCase() {
|
|||
|
||||
fun testGetPreviousConversation() {
|
||||
val service = ConversationService.getInstance()
|
||||
val firstConversation = service.startConversation()
|
||||
service.startConversation()
|
||||
val firstConversation = service.startConversation(project)
|
||||
service.startConversation(project)
|
||||
|
||||
val previousConversation = service.previousConversation
|
||||
|
||||
|
|
@ -46,8 +46,8 @@ class ConversationsStateTest : BasePlatformTestCase() {
|
|||
|
||||
fun testGetNextConversation() {
|
||||
val service = ConversationService.getInstance()
|
||||
val firstConversation = service.startConversation()
|
||||
val secondConversation = service.startConversation()
|
||||
val firstConversation = service.startConversation(project)
|
||||
val secondConversation = service.startConversation(project)
|
||||
ConversationsState.getInstance().setCurrentConversation(firstConversation)
|
||||
|
||||
val nextConversation = service.nextConversation
|
||||
|
|
@ -58,8 +58,8 @@ class ConversationsStateTest : BasePlatformTestCase() {
|
|||
|
||||
fun testDeleteSelectedConversation() {
|
||||
val service = ConversationService.getInstance()
|
||||
val firstConversation = service.startConversation()
|
||||
service.startConversation()
|
||||
val firstConversation = service.startConversation(project)
|
||||
service.startConversation(project)
|
||||
|
||||
service.deleteSelectedConversation()
|
||||
|
||||
|
|
@ -72,8 +72,8 @@ class ConversationsStateTest : BasePlatformTestCase() {
|
|||
|
||||
fun testClearAllConversations() {
|
||||
val service = ConversationService.getInstance()
|
||||
service.startConversation()
|
||||
service.startConversation()
|
||||
service.startConversation(project)
|
||||
service.startConversation(project)
|
||||
|
||||
service.clearAll()
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ class ChatToolWindowTabPanelTest : IntegrationTest() {
|
|||
service<PromptsSettings>().state.personas.selectedPersona.instructions =
|
||||
"TEST_SYSTEM_PROMPT"
|
||||
val message = Message("Hello!")
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val panel = ChatToolWindowTabPanel(project, conversation)
|
||||
expectOpenAI(StreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path).isEqualTo("/v1/chat/completions")
|
||||
|
|
@ -97,7 +97,7 @@ class ChatToolWindowTabPanelTest : IntegrationTest() {
|
|||
val message = Message("TEST_MESSAGE")
|
||||
message.referencedFilePaths =
|
||||
listOf("TEST_FILE_PATH_1", "TEST_FILE_PATH_2", "TEST_FILE_PATH_3")
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val panel = ChatToolWindowTabPanel(project, conversation)
|
||||
panel.includeFiles(listOf(
|
||||
LightVirtualFile("TEST_FILE_NAME_1", "TEST_FILE_CONTENT_1"),
|
||||
|
|
@ -196,7 +196,7 @@ class ChatToolWindowTabPanelTest : IntegrationTest() {
|
|||
service<PromptsSettings>().state.personas.selectedPersona.instructions =
|
||||
"TEST_SYSTEM_PROMPT"
|
||||
val message = Message("TEST_MESSAGE")
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val panel = ChatToolWindowTabPanel(project, conversation)
|
||||
expectOpenAI(StreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path).isEqualTo("/v1/chat/completions")
|
||||
|
|
@ -280,7 +280,7 @@ class ChatToolWindowTabPanelTest : IntegrationTest() {
|
|||
val message = Message("TEST_MESSAGE")
|
||||
message.referencedFilePaths =
|
||||
listOf("TEST_FILE_PATH_1", "TEST_FILE_PATH_2", "TEST_FILE_PATH_3")
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val panel = ChatToolWindowTabPanel(project, conversation)
|
||||
panel.includeFiles(
|
||||
listOf(
|
||||
|
|
@ -391,7 +391,7 @@ class ChatToolWindowTabPanelTest : IntegrationTest() {
|
|||
llamaSettings.minP = 0.03
|
||||
llamaSettings.repeatPenalty = 1.3
|
||||
val message = Message("TEST_PROMPT")
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
val panel = ChatToolWindowTabPanel(project, conversation)
|
||||
expectLlama(StreamHttpExchange { request: RequestEntity ->
|
||||
assertThat(request.uri.path).isEqualTo("/completion")
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ class ChatToolWindowTabbedPaneTest : BasePlatformTestCase() {
|
|||
|
||||
fun testResetCurrentlyActiveTabPanel() {
|
||||
val tabbedPane = ChatToolWindowTabbedPane(Disposer.newDisposable())
|
||||
val conversation = ConversationService.getInstance().startConversation()
|
||||
val conversation = ConversationService.getInstance().startConversation(project)
|
||||
conversation.addMessage(Message("TEST_PROMPT", "TEST_RESPONSE"))
|
||||
tabbedPane.addNewTab(ChatToolWindowTabPanel(project, conversation))
|
||||
|
||||
|
|
@ -44,7 +44,7 @@ class ChatToolWindowTabbedPaneTest : BasePlatformTestCase() {
|
|||
private fun createNewTabPanel(): ChatToolWindowTabPanel {
|
||||
return ChatToolWindowTabPanel(
|
||||
project,
|
||||
ConversationService.getInstance().startConversation()
|
||||
ConversationService.getInstance().startConversation(project)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ class ConversationTagProcessorTest : IntegrationTest() {
|
|||
}
|
||||
|
||||
fun `test should find current conversation by id`() {
|
||||
val conversation = conversationService.startConversation()
|
||||
val conversation = conversationService.startConversation(project)
|
||||
conversation.addMessage(Message("Current conversation test").apply {
|
||||
response = "This is the current conversation"
|
||||
})
|
||||
|
|
@ -134,7 +134,7 @@ class ConversationTagProcessorTest : IntegrationTest() {
|
|||
response = "This is stored"
|
||||
})
|
||||
conversationService.addConversation(storedConversation)
|
||||
val currentConversation = conversationService.startConversation()
|
||||
val currentConversation = conversationService.startConversation(project)
|
||||
currentConversation.id = storedConversation.id
|
||||
currentConversation.addMessage(Message("Current version").apply {
|
||||
response = "This is current"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue