diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/AppServer.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/AppServer.kt index 33bbe4e6..574fd6cb 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/AppServer.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/AppServer.kt @@ -2,7 +2,6 @@ package com.github.simiacryptus.aicoder import com.github.simiacryptus.aicoder.actions.generic.SessionProxyServer import com.github.simiacryptus.aicoder.config.AppSettingsState -import com.github.simiacryptus.aicoder.util.UITools import com.intellij.openapi.progress.ProgressIndicator import com.intellij.openapi.project.Project import com.simiacryptus.skyenet.webui.chat.ChatServer diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/code/CustomEditAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/code/CustomEditAction.kt index ca3f85e1..9f9773eb 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/code/CustomEditAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/code/CustomEditAction.kt @@ -73,7 +73,7 @@ open class CustomEditAction : SelectionAction() { } override fun processSelection(state: SelectionState, instruction: String?): String { - if (instruction == null || instruction.isBlank()) return state.selectedText ?: "" + if (instruction.isNullOrBlank()) return state.selectedText ?: "" return try { UITools.run(state.project, "Processing Edit", true) { progress -> progress.isIndeterminate = true diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/dev/LineFilterChatAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/dev/LineFilterChatAction.kt index acb2eb66..33367753 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/dev/LineFilterChatAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/dev/LineFilterChatAction.kt @@ -22,6 +22,7 @@ import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.chat.ChatSocketManager import com.simiacryptus.skyenet.webui.session.SessionTask import org.slf4j.LoggerFactory +import java.text.SimpleDateFormat class LineFilterChatAction : BaseAction() { private lateinit var lines: List @@ -92,6 +93,7 @@ class LineFilterChatAction : BaseAction() { append("001\n## Injected subtitle\n\n025\n026\n\n013\n014\n") append("```") }.trimMargin() + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.agents[session] = object : ChatSocketManager( session = session, model = AppSettingsState.instance.smartModel.chatModel(), diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CodeChatAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CodeChatAction.kt index d1acd045..fae06b86 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CodeChatAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CodeChatAction.kt @@ -16,6 +16,7 @@ import com.simiacryptus.skyenet.core.platform.Session import com.simiacryptus.skyenet.webui.application.AppInfoData import com.simiacryptus.skyenet.webui.application.ApplicationServer import org.slf4j.LoggerFactory +import java.text.SimpleDateFormat class CodeChatAction : BaseAction() { override fun getActionUpdateThread() = ActionUpdateThread.BGT @@ -43,6 +44,7 @@ class CodeChatAction : BaseAction() { loadImages = false, showMenubar = false ) + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") val server = AppServer.getServer(e.project) diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CommandAutofixAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CommandAutofixAction.kt index 000a4364..cd3784cf 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CommandAutofixAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CommandAutofixAction.kt @@ -22,12 +22,11 @@ import org.slf4j.LoggerFactory import java.awt.BorderLayout import java.io.File import java.nio.file.Files +import java.text.SimpleDateFormat import javax.swing.* import kotlin.collections.set class CommandAutofixAction : BaseAction() { - private lateinit var event: AnActionEvent - /** * Returns the thread that should be used for action update. */ @@ -53,19 +52,18 @@ class CommandAutofixAction : BaseAction() { UITools.showErrorDialog(event.project, "Failed to execute command autofix: ${e.message}", "Error") } } - val folder = UITools.getSelectedFolder(event) - val root = if (null != folder) { - folder.toFile.toPath() - } else { - event.project?.basePath?.let { File(it).toPath() } - }!! - /** * Sets up and launches the patch app session */ private fun setupAndLaunchSession(event: AnActionEvent, settings: PatchApp.Settings, virtualFiles: Array?) { val project = event.project ?: return + val folder = UITools.getSelectedFolder(event) + val root = if (null != folder) { + folder.toFile.toPath() + } else { + event.project?.basePath?.let { File(it).toPath() } + }!! val session = Session.newGlobalID() val patchApp = CmdPatchApp( root, @@ -83,6 +81,7 @@ class CommandAutofixAction : BaseAction() { loadImages = false, showMenubar = false ) + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") val server = AppServer.getServer(event.project) Thread { Thread.sleep(500) diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CreateImageAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CreateImageAction.kt index eae3572f..e8601477 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CreateImageAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/CreateImageAction.kt @@ -37,6 +37,7 @@ import java.io.ByteArrayOutputStream import java.io.File import java.io.IOException import java.nio.file.Path +import java.text.SimpleDateFormat import java.util.concurrent.Semaphore import java.util.concurrent.atomic.AtomicReference import javax.imageio.ImageIO @@ -102,6 +103,7 @@ class CreateImageAction : BaseAction() { loadImages = false, showMenubar = false ) + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") val server = AppServer.getServer(event.project) diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DiffChatAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DiffChatAction.kt index 258bc6ae..c5b89f53 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DiffChatAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DiffChatAction.kt @@ -26,6 +26,7 @@ import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.session.SessionTask import org.intellij.lang.annotations.Language import org.slf4j.LoggerFactory +import java.text.SimpleDateFormat import com.intellij.openapi.application.ApplicationManager as IntellijAppManager class DiffChatAction : BaseAction() { @@ -101,6 +102,7 @@ class DiffChatAction : BaseAction() { ) { var selectionEnd = selectionEnd + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.agents[session] = object : CodeChatSocketManager( session = session, language = language, diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentedMassPatchAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentedMassPatchAction.kt index 1cfd6a6c..c98ca7e5 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentedMassPatchAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/DocumentedMassPatchAction.kt @@ -21,6 +21,7 @@ import java.awt.Dimension import java.io.File import java.nio.file.Files import java.nio.file.Path +import java.text.SimpleDateFormat import javax.swing.* class DocumentedMassPatchAction : BaseAction() { @@ -57,6 +58,7 @@ class DocumentedMassPatchAction : BaseAction() { if (config == null) return val session = Session.newGlobalID() + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.chats[session] = DocumentedMassPatchServer( config = config, api = api, diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/GenericChatAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/GenericChatAction.kt index 72e21f48..cd8d6ce8 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/GenericChatAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/GenericChatAction.kt @@ -15,6 +15,7 @@ import com.simiacryptus.skyenet.webui.application.AppInfoData import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.chat.ChatSocketManager import org.slf4j.LoggerFactory +import java.text.SimpleDateFormat class GenericChatAction : BaseAction() { override fun getActionUpdateThread() = ActionUpdateThread.BGT @@ -33,6 +34,7 @@ class GenericChatAction : BaseAction() { progress.text = "Setting up chat session..." val session = Session.newGlobalID() + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.agents[session] = ChatSocketManager( session = session, model = model, diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MassPatchAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MassPatchAction.kt index efefcb39..844ab872 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MassPatchAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MassPatchAction.kt @@ -36,6 +36,7 @@ import java.awt.BorderLayout import java.awt.Dimension import java.nio.file.Files import java.nio.file.Path +import java.text.SimpleDateFormat import java.util.* import java.util.concurrent.Semaphore import java.util.concurrent.atomic.AtomicReference @@ -54,10 +55,13 @@ class MassPatchAction : BaseAction() { class SettingsUI { @Name("Files to Process") val filesToProcess = CheckBoxList() + @Name("AI Instruction") val transformationMessage = JBTextArea(4, 40) + @Name("Recent Instructions") val recentInstructions = JComboBox() + @Name("Auto Apply") val autoApply = JCheckBox("Auto Apply Changes") } @@ -122,27 +126,32 @@ class MassPatchAction : BaseAction() { return } - val session = Session.newGlobalID() - SessionProxyServer.chats[session] = MassPatchServer(config=config!!, api=api, autoApply = config.settings?.autoApply ?: false) - ApplicationServer.appInfoMap[session] = AppInfoData( - applicationName = "Code Chat", - singleInput = true, - stickyInput = false, - loadImages = false, - showMenubar = false - ) + val session = Session.newGlobalID() + SessionProxyServer.metadataStorage.setSessionName( + null, + session, + "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}" + ) + SessionProxyServer.chats[session] = MassPatchServer(config = config!!, api = api, autoApply = config.settings?.autoApply ?: false) + ApplicationServer.appInfoMap[session] = AppInfoData( + applicationName = "Code Chat", + singleInput = true, + stickyInput = false, + loadImages = false, + showMenubar = false + ) val server = AppServer.getServer(event.project) UITools.run(project, "Opening browser") { - Thread.sleep(500) - try { - val uri = server.server.uri.resolve("/#$session") - log.info("Opening browser to $uri") - browse(uri) - } catch (e: Throwable) { - log.warn("Error opening browser", e) - UITools.showErrorDialog(project, "Failed to open browser: ${e.message}", "Error") - } + Thread.sleep(500) + try { + val uri = server.server.uri.resolve("/#$session") + log.info("Opening browser to $uri") + browse(uri) + } catch (e: Throwable) { + log.warn("Error opening browser", e) + UITools.showErrorDialog(project, "Failed to open browser: ${e.message}", "Error") + } } } catch (e: Exception) { log.error("Error in mass patch action", e) @@ -156,7 +165,7 @@ class MassPatchAction : BaseAction() { init { this.title = title - // Set the default values for the UI elements from userSettings +// Set the default values for the UI elements from userSettings settingsUI.transformationMessage.text = userSettings.transformationMessage settingsUI.autoApply.isSelected = userSettings.autoApply init() @@ -215,43 +224,43 @@ class MassPatchServer( return SimpleActor( prompt = """ - |You are a helpful AI that helps people with coding. - | - |Response should use one or more code patches in diff format within ```diff code blocks. - |Each diff should be preceded by a header that identifies the file being modified. - |The diff format should use + for line additions, - for line deletions. - |The diff should include 2 lines of context before and after every change. - | - |Example: - | - |Here are the patches: - | - |### src/utils/exampleUtils.js - |```diff - | // Utility functions for example feature - | const b = 2; - | function exampleFunction() { - |- return b + 1; - |+ return b + 2; - | } - |``` - | - |### tests/exampleUtils.test.js - |```diff - | // Unit tests for exampleUtils - | const assert = require('assert'); - | const { exampleFunction } = require('../src/utils/exampleUtils'); - | - | describe('exampleFunction', () => { - |- it('should return 3', () => { - |+ it('should return 4', () => { - | assert.equal(exampleFunction(), 3); - | }); - | }); - |``` - | - |If needed, new files can be created by using code blocks labeled with the filename in the same manner. - """.trimMargin(), +|You are a helpful AI that helps people with coding. +| +|Response should use one or more code patches in diff format within ```diff code blocks. +|Each diff should be preceded by a header that identifies the file being modified. +|The diff format should use + for line additions, - for line deletions. +|The diff should include 2 lines of context before and after every change. +| +|Example: +| +|Here are the patches: +| +|### src/utils/exampleUtils.js +|```diff +| // Utility functions for example feature +| const b = 2; +| function exampleFunction() { +|- return b + 1; +|+ return b + 2; +| } +|``` +| +|### tests/exampleUtils.test.js +|```diff +| // Unit tests for exampleUtils +| const assert = require('assert'); +| const { exampleFunction } = require('../src/utils/exampleUtils'); +| +| describe('exampleFunction', () => { +|- it('should return 3', () => { +|+ it('should return 4', () => { +| assert.equal(exampleFunction(), 3); +| }); +| }); +|``` +| +|If needed, new files can be created by using code blocks labeled with the filename in the same manner. +""".trimMargin(), model = AppSettingsState.instance.smartModel.chatModel(), temperature = AppSettingsState.instance.temperature, ) @@ -289,11 +298,11 @@ class MassPatchServer( ?.entries?.joinToString("\n\n") { (path, code) -> val extension = path.toString().split('.').lastOrNull() """ - |# $path - |```$extension - |${code.let { /*escapeHtml4*/(it)/*.indent(" ")*/ }} - |``` - """.trimMargin() +|# $path +|```$extension +|${code.let { /*escapeHtml4*/(it)/*.indent(" ")*/ }} +|``` +""".trimMargin() } val fileTask = ui.newTask(false).apply { tabs[path.toString()] = placeholder diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiCodeChatAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiCodeChatAction.kt index 55f60b75..13de0b76 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiCodeChatAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiCodeChatAction.kt @@ -27,6 +27,7 @@ import com.simiacryptus.skyenet.webui.application.ApplicationServer import org.slf4j.LoggerFactory import java.io.File import java.nio.file.Path +import java.text.SimpleDateFormat import java.util.* /** @@ -72,6 +73,7 @@ class MultiCodeChatAction : BaseAction() { progress.isIndeterminate = true progress.text = "Setting up chat session..." val session = Session.newGlobalID() + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.chats[session] = PatchApp(root.toFile(), { codeSummary() }, codeFiles) ApplicationServer.appInfoMap[session] = AppInfoData( applicationName = "Code Chat", diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiDiffChatAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiDiffChatAction.kt index dd51c6c3..2131d7cd 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiDiffChatAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiDiffChatAction.kt @@ -30,6 +30,7 @@ import com.simiacryptus.skyenet.webui.application.ApplicationServer import org.slf4j.LoggerFactory import java.io.File import java.nio.file.Path +import java.text.SimpleDateFormat import java.util.* import java.util.concurrent.Semaphore import java.util.concurrent.atomic.AtomicReference @@ -59,6 +60,7 @@ class MultiDiffChatAction : BaseAction() { } val initialFiles = getFiles(virtualFiles, root) val session = Session.newGlobalID() + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.chats[session] = PatchApp(root.toFile(), initialFiles) ApplicationServer.appInfoMap[session] = AppInfoData( applicationName = "Code Chat", diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiStepPatchAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiStepPatchAction.kt index 4de580bb..33b76064 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiStepPatchAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/MultiStepPatchAction.kt @@ -39,6 +39,7 @@ import com.simiacryptus.util.JsonUtil.toJson import org.slf4j.LoggerFactory import java.io.File import java.nio.file.Path +import java.text.SimpleDateFormat import java.util.concurrent.Semaphore import java.util.concurrent.atomic.AtomicReference @@ -64,6 +65,7 @@ class MultiStepPatchAction : BaseAction() { if (null != storage && null != selectedFile) { DataStorage.sessionPaths[session] = selectedFile.toFile } + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.chats[session] = AutoDevApp(event = e) ApplicationServer.appInfoMap[session] = AppInfoData( applicationName = "Code Chat", diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SessionProxyApp.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SessionProxyApp.kt index 75f1eb58..b1ca6e2a 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SessionProxyApp.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SessionProxyApp.kt @@ -1,6 +1,8 @@ package com.github.simiacryptus.aicoder.actions.generic +import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.Session +import com.simiacryptus.skyenet.core.platform.model.ApplicationServicesConfig.dataStorageRoot import com.simiacryptus.skyenet.core.platform.model.User import com.simiacryptus.skyenet.webui.application.AppInfoData import com.simiacryptus.skyenet.webui.application.ApplicationServer @@ -25,11 +27,11 @@ class SessionProxyServer : ApplicationServer( }.toMap() override fun newSession(user: User?, session: Session) = - chats[session]?.newSession(user, session) ?: agents[session]!! + chats[session]?.newSession(user, session) ?: agents[session] ?: throw IllegalStateException("No agent found for session $session") companion object { private val log = org.slf4j.LoggerFactory.getLogger(SessionProxyServer::class.java) - + val metadataStorage by lazy { ApplicationServices.metadataStorageFactory(dataStorageRoot) } val agents = mutableMapOf() val chats = mutableMapOf() } diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/ShellCommandAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/ShellCommandAction.kt index 26157e01..b72cf8a1 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/ShellCommandAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/ShellCommandAction.kt @@ -19,6 +19,7 @@ import com.simiacryptus.skyenet.webui.application.AppInfoData import com.simiacryptus.skyenet.webui.application.ApplicationInterface import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.session.SessionTask +import java.text.SimpleDateFormat class ShellCommandAction : BaseAction() { override fun getActionUpdateThread() = ActionUpdateThread.BGT @@ -56,6 +57,7 @@ class ShellCommandAction : BaseAction() { showMenubar = false ) + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.chats[session] = object : ApplicationServer( applicationName = "Shell Agent", path = "/shellAgent", diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SimpleCommandAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SimpleCommandAction.kt index 9c6df23c..6cb4b170 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SimpleCommandAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/SimpleCommandAction.kt @@ -33,6 +33,7 @@ import org.slf4j.LoggerFactory import java.io.File import java.nio.file.Files import java.nio.file.Path +import java.text.SimpleDateFormat import kotlin.io.path.ExperimentalPathApi import kotlin.io.path.walk @@ -60,6 +61,7 @@ class SimpleCommandAction : BaseAction() { progress.text = "Creating patch application..." val patchApp = createPatchApp(root.toFile(), session, settings, virtualFiles) progress.text = "Configuring session..." + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.chats[session] = patchApp ApplicationServer.appInfoMap[session] = AppInfoData( applicationName = "Code Chat", diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/WebDevelopmentAssistantAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/WebDevelopmentAssistantAction.kt index 2339260c..6d7bd920 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/WebDevelopmentAssistantAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/generic/WebDevelopmentAssistantAction.kt @@ -37,6 +37,7 @@ import org.slf4j.LoggerFactory import java.io.ByteArrayOutputStream import java.io.File import java.nio.file.Path +import java.text.SimpleDateFormat import java.util.concurrent.Semaphore import java.util.concurrent.atomic.AtomicReference import javax.imageio.ImageIO @@ -61,6 +62,7 @@ class WebDevelopmentAssistantAction : BaseAction() { val session = Session.newGlobalID() val selectedFile = UITools.getSelectedFolder(e) ?: return DataStorage.sessionPaths[session] = selectedFile.toFile + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.chats[session] = WebDevApp(root = selectedFile) ApplicationServer.appInfoMap[session] = AppInfoData( applicationName = "Code Chat", diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithCommitAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithCommitAction.kt index 9a9804b0..1b46bfc3 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithCommitAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithCommitAction.kt @@ -20,6 +20,7 @@ import com.simiacryptus.skyenet.core.platform.Session import com.simiacryptus.skyenet.webui.application.AppInfoData import com.simiacryptus.skyenet.webui.application.ApplicationServer import java.io.File +import java.text.SimpleDateFormat val String.isBinary: Boolean get() { @@ -86,6 +87,7 @@ class ChatWithCommitAction : AnAction() { loadImages = false, showMenubar = false ) + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") val server = AppServer.getServer(e.project) diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithCommitDiffAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithCommitDiffAction.kt index 7520f024..9ba2b4e6 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithCommitDiffAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithCommitDiffAction.kt @@ -25,6 +25,7 @@ import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.Session import com.simiacryptus.skyenet.webui.application.AppInfoData import com.simiacryptus.skyenet.webui.application.ApplicationServer +import java.text.SimpleDateFormat import com.intellij.openapi.application.ApplicationManager as IntellijAppManager class ChatWithCommitDiffAction : BaseAction( @@ -77,6 +78,7 @@ class ChatWithCommitDiffAction : BaseAction( loadImages = false, showMenubar = false ) + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") val server = AppServer.getServer(e.project) diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithWorkingCopyDiffAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithWorkingCopyDiffAction.kt index 92f0b112..132e2804 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithWorkingCopyDiffAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ChatWithWorkingCopyDiffAction.kt @@ -16,6 +16,7 @@ import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.Session import com.simiacryptus.skyenet.webui.application.AppInfoData import com.simiacryptus.skyenet.webui.application.ApplicationServer +import java.text.SimpleDateFormat import javax.swing.JOptionPane class ChatWithWorkingCopyDiffAction : AnAction() { @@ -58,6 +59,7 @@ class ChatWithWorkingCopyDiffAction : AnAction() { loadImages = false, showMenubar = false ) + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") val server = AppServer.getServer(e.project) diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ReplicateCommitAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ReplicateCommitAction.kt index 8d3e5472..60fb253a 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ReplicateCommitAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/git/ReplicateCommitAction.kt @@ -39,6 +39,7 @@ import org.slf4j.LoggerFactory import java.io.File import java.nio.file.Files import java.nio.file.Path +import java.text.SimpleDateFormat import kotlin.io.path.ExperimentalPathApi import kotlin.io.path.walk @@ -104,6 +105,7 @@ class ReplicateCommitAction : BaseAction() { } } progress.text = "Setting up session..." + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.chats[session] = patchApp ApplicationServer.appInfoMap[session] = AppInfoData( applicationName = "Code Chat", diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/knowledge/CreateProjectorFromQueryIndexAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/knowledge/CreateProjectorFromQueryIndexAction.kt index e7296e1f..74462bac 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/knowledge/CreateProjectorFromQueryIndexAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/knowledge/CreateProjectorFromQueryIndexAction.kt @@ -19,6 +19,7 @@ import com.simiacryptus.skyenet.webui.application.ApplicationServer import com.simiacryptus.skyenet.webui.application.ApplicationSocketManager import com.simiacryptus.skyenet.webui.session.SocketManager import org.slf4j.LoggerFactory +import java.text.SimpleDateFormat class CreateProjectorFromQueryIndexAction : BaseAction() { data class ProjectorConfig( @@ -85,6 +86,7 @@ class CreateProjectorFromQueryIndexAction : BaseAction() { return socketManager } } + SessionProxyServer.metadataStorage.setSessionName(null, config.sessionId, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") indicator.fraction = 1.0 indicator.text = "Opening browser..." diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/knowledge/DocumentDataExtractorAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/knowledge/DocumentDataExtractorAction.kt index daa6e68a..c47cc90e 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/knowledge/DocumentDataExtractorAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/knowledge/DocumentDataExtractorAction.kt @@ -24,6 +24,7 @@ import com.simiacryptus.skyenet.webui.application.ApplicationServer import org.slf4j.LoggerFactory import java.io.File import java.nio.file.Path +import java.text.SimpleDateFormat class DocumentDataExtractorAction : BaseAction( name = "Extract Document Data", @@ -90,6 +91,7 @@ class DocumentDataExtractorAction : BaseAction( val parsingModel = ParsingModelType.getImpl(smartModel, 0.1, modelType) progress.text = "Initializing document parser..." + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.chats[session] = object : DocumentParserApp( applicationName = "Document Extractor", path = this@DocumentDataExtractorAction.path, @@ -102,6 +104,7 @@ class DocumentDataExtractorAction : BaseAction( override val root: File get() = selectedFile.parent.toFile } val sessionId = Session.newGlobalID() + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.chats[session] = DocumentParserApp( applicationName = "Document Extractor", path = path, diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/AutoPlanChatAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/AutoPlanChatAction.kt index 90512066..5edd5065 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/AutoPlanChatAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/AutoPlanChatAction.kt @@ -24,6 +24,7 @@ import com.simiacryptus.skyenet.webui.application.AppInfoData import com.simiacryptus.skyenet.webui.application.ApplicationServer import java.io.File import java.nio.file.Path +import java.text.SimpleDateFormat class AutoPlanChatAction : BaseAction() { // Maximum file size to process (512KB) @@ -90,6 +91,7 @@ class AutoPlanChatAction : BaseAction() { loadImages = false, showMenubar = false ) + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") } private fun createChatApp(root: File, e: AnActionEvent, dialog: PlanAheadConfigDialog) = diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/PlanAheadAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/PlanAheadAction.kt index 5f1b6ed5..81d04aa2 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/PlanAheadAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/PlanAheadAction.kt @@ -60,7 +60,7 @@ class PlanAheadAction : BaseAction() { ), parsingModel = AppSettingsState.instance.fastModel.chatModel(), ) - SessionProxyServer.Companion.chats[session] = PlanAheadApp( + SessionProxyServer.chats[session] = PlanAheadApp( planSettings = planSettings, model = AppSettingsState.instance.smartModel.chatModel(), parsingModel = AppSettingsState.instance.fastModel.chatModel(), diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/PlanChatAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/PlanChatAction.kt index 4d7a5638..df2b3398 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/PlanChatAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/plan/PlanChatAction.kt @@ -78,7 +78,7 @@ class PlanChatAction : BaseAction() { UITools.getSelectedFile(e)?.parent?.toFile ?: throw RuntimeException("") ) DataStorage.sessionPaths[session] = root - SessionProxyServer.Companion.chats[session] = PlanChatApp( + SessionProxyServer.chats[session] = PlanChatApp( planSettings = settings.copy( env = mapOf(), workingDir = root.absolutePath, diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/problems/AnalyzeProblemAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/problems/AnalyzeProblemAction.kt index 52fdbd52..feb01283 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/problems/AnalyzeProblemAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/problems/AnalyzeProblemAction.kt @@ -39,6 +39,7 @@ import com.simiacryptus.skyenet.webui.application.ApplicationSocketManager import com.simiacryptus.skyenet.webui.session.SessionTask import com.simiacryptus.skyenet.webui.session.SocketManager import com.simiacryptus.util.JsonUtil +import java.text.SimpleDateFormat import javax.swing.JOptionPane class AnalyzeProblemAction : AnAction() { @@ -113,6 +114,7 @@ class AnalyzeProblemAction : AnAction() { loadImages = false, showMenubar = false ) + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") val server = AppServer.getServer(project) diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/test/TestResultAutofixAction.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/test/TestResultAutofixAction.kt index 7176c0e7..68129e27 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/actions/test/TestResultAutofixAction.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/actions/test/TestResultAutofixAction.kt @@ -33,6 +33,7 @@ import org.jetbrains.annotations.NotNull import org.slf4j.LoggerFactory import java.io.File import java.nio.file.Path +import java.text.SimpleDateFormat class TestResultAutofixAction : BaseAction() { companion object { @@ -155,6 +156,7 @@ class TestResultAutofixAction : BaseAction() { private fun openAutofixWithTestResult(e: AnActionEvent, testInfo: String, projectStructure: String) { val session = Session.newGlobalID() + SessionProxyServer.metadataStorage.setSessionName(null, session, "${javaClass.simpleName} @ ${SimpleDateFormat("HH:mm:ss").format(System.currentTimeMillis())}") SessionProxyServer.chats[session] = TestResultAutofixApp(session, testInfo, e.project?.basePath, projectStructure) ApplicationServer.appInfoMap[session] = AppInfoData( applicationName = "Code Chat", diff --git a/src/main/kotlin/com/github/simiacryptus/aicoder/ui/SettingsWidgetFactory.kt b/src/main/kotlin/com/github/simiacryptus/aicoder/ui/SettingsWidgetFactory.kt index b1e3df48..fed3fe08 100644 --- a/src/main/kotlin/com/github/simiacryptus/aicoder/ui/SettingsWidgetFactory.kt +++ b/src/main/kotlin/com/github/simiacryptus/aicoder/ui/SettingsWidgetFactory.kt @@ -19,12 +19,15 @@ import com.intellij.ui.treeStructure.Tree import com.simiacryptus.jopenai.models.ChatModel import com.simiacryptus.skyenet.core.platform.ApplicationServices import com.simiacryptus.skyenet.core.platform.Session +import com.simiacryptus.skyenet.core.platform.file.DataStorage +import com.simiacryptus.skyenet.core.platform.model.ApplicationServicesConfig.dataStorageRoot import icons.MyIcons import kotlinx.coroutines.CoroutineScope import java.awt.* import java.awt.datatransfer.StringSelection import java.awt.event.MouseAdapter import java.awt.event.MouseEvent +import java.io.File import java.net.URI import javax.swing.* import javax.swing.tree.DefaultMutableTreeNode @@ -176,7 +179,7 @@ class SettingsWidgetFactory : StatusBarWidgetFactory { return "http://${settings.listeningEndpoint}:${settings.listeningPort}/?session=${session.sessionId}" } - private class SessionListRenderer : ListCellRenderer { + private inner class SessionListRenderer : ListCellRenderer { private val label = JLabel() override fun getListCellRendererComponent( list: JList?, @@ -185,7 +188,20 @@ class SettingsWidgetFactory : StatusBarWidgetFactory { isSelected: Boolean, cellHasFocus: Boolean ): Component { - label.text = "Session ${value?.sessionId?.take(8)}" + label.text = if (value != null) { + try { + val sessionName = ApplicationServices.metadataStorageFactory(dataStorageRoot).getSessionName(null, value) + when { + sessionName.isNullOrBlank() -> getDefaultSessionLabel(value) + else -> "$sessionName (${value.sessionId.take(8)})" + } + } catch (e: Exception) { + getDefaultSessionLabel(value) + } + } else { + "Unknown Session" + } + if (isSelected) { label.background = list?.selectionBackground label.foreground = list?.selectionForeground @@ -195,6 +211,9 @@ class SettingsWidgetFactory : StatusBarWidgetFactory { } return label } + private fun getDefaultSessionLabel(session: Session): String { + return "Session ${session.sessionId.take(8)}" + } } init {