1+ package com.github.simiacryptus.aicoder.actions.generic
2+
3+ import com.github.simiacryptus.aicoder.AppServer
4+ import com.github.simiacryptus.aicoder.actions.BaseAction
5+ import com.github.simiacryptus.aicoder.config.AppSettingsState
6+ import com.github.simiacryptus.aicoder.config.AppSettingsState.Companion.chatModel
7+ import com.intellij.openapi.actionSystem.ActionUpdateThread
8+ import com.intellij.openapi.actionSystem.AnActionEvent
9+ import com.intellij.openapi.actionSystem.CommonDataKeys
10+ import com.intellij.openapi.project.Project
11+ import com.intellij.xdebugger.XDebuggerManager
12+ import com.simiacryptus.skyenet.core.platform.ApplicationServices
13+ import com.simiacryptus.skyenet.core.platform.Session
14+ import com.simiacryptus.skyenet.core.platform.StorageInterface
15+ import com.simiacryptus.skyenet.core.platform.User
16+ import com.simiacryptus.skyenet.webui.application.ApplicationServer
17+ import com.simiacryptus.skyenet.webui.chat.ChatServer
18+ import com.simiacryptus.skyenet.webui.chat.ChatSocketManager
19+ import com.simiacryptus.skyenet.webui.session.SocketManager
20+ import org.slf4j.LoggerFactory
21+ import java.awt.Desktop
22+ import java.io.File
23+
24+ class DebugChatAction : BaseAction () {
25+ override fun getActionUpdateThread () = ActionUpdateThread .BGT
26+
27+ val path = " /codeChat"
28+ val model = AppSettingsState .instance.smartModel.chatModel()
29+
30+ override fun handle (e : AnActionEvent ) {
31+ val project = e.getData(CommonDataKeys .PROJECT )
32+ val debugSessionInfo = getDebugSessionInfo(project)
33+ val systemPrompt = debugSessionInfo
34+ val userInterfacePrompt = " "
35+ val session = StorageInterface .newGlobalID()
36+ agents[session] = ChatSocketManager (
37+ session = session,
38+ model = model,
39+ initialAssistantPrompt = " " ,
40+ userInterfacePrompt = userInterfacePrompt,
41+ systemPrompt = systemPrompt,
42+ api = api,
43+ storage = ApplicationServices .dataStorageFactory(root),
44+ applicationClass = ApplicationServer ::class .java,
45+ )
46+
47+ val server = AppServer .getServer(e.project)
48+ val app = initApp(server, path)
49+ app.sessions[session] = app.newSession(null , session)
50+
51+ Thread {
52+ Thread .sleep(500 )
53+ try {
54+ Desktop .getDesktop().browse(server.server.uri.resolve(" $path /#$session " ))
55+ } catch (e: Throwable ) {
56+ log.warn(" Error opening browser" , e)
57+ }
58+ }.start()
59+ }
60+
61+ private fun getDebugSessionInfo (project : Project ? ): String {
62+ val debugSession = XDebuggerManager .getInstance(project ? : return " No project found" ).currentSession
63+ val stackFrame = debugSession?.currentStackFrame ? : return " No stack frames found"
64+ val frameContext = stackFrame.sourcePosition?.let {
65+ val lines = it.file.toFile.readLines()
66+ val context = ((it.line - 2 ) until (it.line + 2 )).map { line -> lines.getOrNull(line) }
67+ context.joinToString(" \n " )
68+ }
69+ // val frameVars = debugSession..map { it.name to it.value?.toString() }
70+ return frameContext.toString()
71+ }
72+
73+ override fun isEnabled (event : AnActionEvent ) = true
74+
75+ companion object {
76+ private val log = LoggerFactory .getLogger(CodeChatAction ::class .java)
77+ private val agents = mutableMapOf<Session , SocketManager >()
78+ val root: File get() = File (AppSettingsState .instance.pluginHome, " code_chat" )
79+ private fun initApp (server : AppServer , path : String ): ChatServer {
80+ server.appRegistry[path]?.let { return it }
81+ val socketServer = object : ApplicationServer (
82+ applicationName = " Code Chat" ,
83+ path = path,
84+ showMenubar = false ,
85+ ) {
86+ override val singleInput = false
87+ override val stickyInput = true
88+ override fun newSession (user : User ? , session : Session ) =
89+ agents[session] ? : throw IllegalArgumentException (" Unknown session: $session " )
90+ }
91+ server.addApp(path, socketServer)
92+ return socketServer
93+ }
94+
95+ }
96+ }
0 commit comments