Skip to content

Commit

Permalink
1.2.17
Browse files Browse the repository at this point in the history
  • Loading branch information
acharneski committed Oct 26, 2023
1 parent 500a1d5 commit e9d720e
Show file tree
Hide file tree
Showing 15 changed files with 336 additions and 233 deletions.
4 changes: 2 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ repositories {
val kotlin_version = "1.7.22"
val jetty_version = "11.0.15"
val slf4j_version = "2.0.5"
val skyenet_version = "1.0.17"
val skyenet_version = "1.0.18"
dependencies {

implementation(group = "com.simiacryptus", name = "joe-penai", version = "1.0.19")
implementation(group = "com.simiacryptus", name = "joe-penai", version = "1.0.20")

implementation(group = "com.simiacryptus.skyenet", name = "util", version = skyenet_version)
implementation(group = "com.simiacryptus.skyenet", name = "core", version = skyenet_version)
Expand Down
4 changes: 2 additions & 2 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version ("0.4.0")
}

//includeBuild("../joe-penai/")
//includeBuild("../SkyeNet/")
includeBuild("../joe-penai/")
includeBuild("../SkyeNet/")
//includeBuild("../AwsAgent/")


Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package com.github.simiacryptus.aicoder.actions.code
import com.github.simiacryptus.aicoder.actions.SelectionAction
import com.github.simiacryptus.aicoder.config.AppSettingsState
import com.github.simiacryptus.aicoder.util.ComputerLanguage
import com.github.simiacryptus.aicoder.util.UITools
import com.github.simiacryptus.aicoder.util.psi.PsiClassContext
import com.github.simiacryptus.aicoder.util.psi.PsiUtil
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.Project
import com.simiacryptus.openai.proxy.ChatProxy
import kotlin.Pair
Expand Down Expand Up @@ -85,18 +87,20 @@ class InsertImplementationAction extends SelectionAction<String> {
.filter { x -> !x.isEmpty() }
.reduce { a, b -> "$a $b" }.get()
if(null != state.psiFile) {
def psiClassContext = PsiClassContext.getContext(
state.psiFile,
psiClassContextActionParams.selectionStart,
psiClassContextActionParams.selectionEnd,
computerLanguage
).toString()
def code = proxy.implementCode(
specification,
psiClassContext,
computerLanguage.name(),
humanLanguage,
).code
def code = UITools.run(state.project, "Insert Implementation", true, true, {
def psiClassContext = PsiClassContext.getContext(
state.psiFile,
psiClassContextActionParams.selectionStart,
psiClassContextActionParams.selectionEnd,
computerLanguage
).toString()
proxy.implementCode(
specification,
psiClassContext,
computerLanguage.name(),
humanLanguage,
).code
})
if(null != code) return selectedText + "\n${state.indent}" + code
} else {
def code = proxy.implementCode(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import org.jetbrains.annotations.Nullable

import java.awt.Toolkit
import java.awt.datatransfer.DataFlavor
import java.awt.datatransfer.Transferable

class PasteAction extends SelectionAction<String> {
PasteAction() {
Expand Down Expand Up @@ -62,6 +63,8 @@ class PasteAction extends SelectionAction<String> {
}

private Object getClipboard() {
return Toolkit.getDefaultToolkit().systemClipboard.getContents(null)?.getTransferData(DataFlavor.stringFlavor)
def contents = Toolkit.getDefaultToolkit().systemClipboard.getContents(null)
if (contents?.isDataFlavorSupported(DataFlavor.stringFlavor) == true) contents?.getTransferData(DataFlavor.stringFlavor)
else null
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ abstract class SelectionAction<T : Any>(
indent = indent,
contextRanges = editorState.contextRanges,
psiFile = editorState.psiFile,
project = event.project
),
config = config
)
Expand Down Expand Up @@ -171,6 +172,7 @@ abstract class SelectionAction<T : Any>(
val indent: CharSequence? = null,
val contextRanges: Array<ContextRange> = arrayOf(),
val psiFile: PsiFile?,
val project: Project?
)

open fun isLanguageSupported(computerLanguage: ComputerLanguage?): Boolean {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package com.github.simiacryptus.aicoder.actions.dev

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.body.WebSocketServer
import org.eclipse.jetty.server.Server
import org.eclipse.jetty.server.handler.ContextHandlerCollection
import org.eclipse.jetty.webapp.WebAppContext
import org.eclipse.jetty.websocket.server.config.JettyWebSocketServletContainerInitializer
import org.slf4j.LoggerFactory
import java.net.InetSocketAddress

class AppServer(
val localName: String,
val port: Int,
project: Project?
) {

val log by lazy { LoggerFactory.getLogger(javaClass) }

var domainName: String = "http://$localName:$port"

private val contexts by lazy {
val contexts = ContextHandlerCollection()
contexts.handlers = handlers.toTypedArray()
contexts
}

@Synchronized
fun addApp(path: String, socketServer: WebSocketServer) {
try {
synchronized(serverLock) {
if (server.isRunning) server.stop() // Stop the server
handlers += newWebAppContext(socketServer, path)
contexts.handlers = handlers.toTypedArray()
server.handler = contexts
server.start() // Start the server again to reflect the new context
}
} catch (e: Exception) {
log.error("Error while restarting the server with new context", e)
}
}

fun newWebAppContext(server: WebSocketServer, path: String): WebAppContext {
val context = WebAppContext()
JettyWebSocketServletContainerInitializer.configure(context, null)
context.baseResource = server.baseResource
context.contextPath = path
context.welcomeFiles = arrayOf("index.html")
val webAppContext = context
server.configure(webAppContext, baseUrl = "$domainName/$path")
return webAppContext
}

private val handlers = arrayOf<WebAppContext>().toMutableList()

val server by lazy {
val server = Server(InetSocketAddress(localName, port))
server.handler = contexts
server
}

private val serverLock = Object()
private val progressThread = Thread {
try {
UITools.run(
project, "Running CodeChat Server on $port", false
) {
while (isRunning(it)) {
Thread.sleep(1000)
}
synchronized(serverLock) {
if (it.isCanceled) {
log.info("Server cancelled")
server.stop()
} else {
log.info("Server stopped")
}
}
}
} finally {
log.info("Stopping Server")
server.stop()
}
}

fun isRunning(it: ProgressIndicator) = synchronized(serverLock) { !it.isCanceled && server.isRunning }
fun start() {
server.start()
progressThread.start()
}

companion object {
@Transient
private var server: AppServer? = null
fun getServer(project: Project?): AppServer {
if (null == server || !server!!.server.isRunning) {
server = AppServer(
AppSettingsState.instance.listeningEndpoint,
AppSettingsState.instance.listeningPort,
project
)
server!!.start()
}
return server!!
}

fun stop() {
server?.server?.stop()
server = null
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -8,140 +8,24 @@ import com.github.simiacryptus.aicoder.util.ComputerLanguage
import com.github.simiacryptus.aicoder.util.UITools
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.simiacryptus.openai.OpenAIClient.ChatMessage
import com.simiacryptus.openai.OpenAIClient.ChatRequest
import com.simiacryptus.skyenet.Heart
import com.simiacryptus.skyenet.body.*
import com.simiacryptus.skyenet.heart.WeakGroovyInterpreter
import org.eclipse.jetty.util.resource.Resource
import java.awt.Desktop
import java.util.function.Supplier
import java.util.*

class CodeChatAction : BaseAction() {

inner class CodeChatServer(
val e: AnActionEvent,
port: Int,
val language: String,
val codeSelection: String,
baseURL: String = "http://localhost:$port",
) : SkyenetCodingSessionServer(
applicationName = "Code Chat",
model = AppSettingsState.instance.defaultChatModel(),
apiKey = AppSettingsState.instance.apiKey,
) {

val rootOperationID = (0..5).map { ('a'..'z').random() }.joinToString("")
var rootMessageTrail: String = ""

override fun newSession(sessionId: String): SkyenetCodingSession {
val newSession = CodeChatSession(sessionId)
rootMessageTrail =
"""$rootOperationID,<div><h3>Code:</h3><pre><code class="language-$language">${htmlEscape(codeSelection)}</code></pre></div>"""
newSession.send(rootMessageTrail)
return newSession
}

private fun htmlEscape(html: String): String {
return html.replace("&", "&amp;").replace("<", "&lt;")
.replace(">", "&gt;").replace("\"", "&quot;")
.replace("'", "&#039;")
}

open inner class CodeChatSession(sessionId: String) : SkyenetCodingSession(sessionId, this@CodeChatServer) {
override fun run(userMessage: String) {
var messageTrail = ChatSession.divInitializer()
send("""$messageTrail<div>$userMessage</div><div>$spinner</div>""")
messages += ChatMessage(ChatMessage.Role.user, userMessage)
val response = api.chat(chatRequest, model).choices.first()?.message?.content.orEmpty()
messages += ChatMessage(ChatMessage.Role.assistant, response)
messageTrail += ChatSessionFlexmark.renderMarkdown(response)
send(messageTrail)
}

val messages = listOf(
ChatMessage(
ChatMessage.Role.system, """
|You are a helpful AI that helps people with coding.
|
|You will be answering questions about the following code:
|
|```$language
|$codeSelection
|```
|
|Responses may use markdown formatting.
""".trimMargin()
)
).toMutableList()
val chatRequest: ChatRequest
get() {
val chatRequest = ChatRequest()
val model = AppSettingsState.instance.defaultChatModel()
chatRequest.model = model.modelName
chatRequest.max_tokens = model.maxTokens
chatRequest.temperature = AppSettingsState.instance.temperature
chatRequest.messages = messages.toTypedArray()
return chatRequest
}
}

override val baseResource: Resource
get() = ClasspathResource(javaClass.classLoader.getResource(resourceBase))

override fun hands() = java.util.HashMap<String, Object>() as java.util.Map<String, Object>

override fun toString(e: Throwable): String {
return e.message ?: e.toString()
}

override fun heart(hands: java.util.Map<String, Object>): Heart = object : WeakGroovyInterpreter(hands) {
override fun <T : Any> wrapExecution(fn: Supplier<T?>): T? {
return UITools.run(
e.project, "Running Script", false
) {
fn.get()
}
}
}
}

override fun handle(event: AnActionEvent) {
val editor = event.getData(CommonDataKeys.EDITOR) ?: return
val caretModel = editor.caretModel
val primaryCaret = caretModel.primaryCaret
val selectedText = primaryCaret.selectedText ?: editor.document.text
val language = ComputerLanguage.getComputerLanguage(event)?.name ?: return

val port = (8000 + (Math.random() * 8000).toInt())
val skyenet = CodeChatServer(event, port, language, selectedText, baseURL = "http://localhost:$port")
val server = skyenet.start(port)

Thread {
try {
UITools.run(
event.project, "Running CodeChat Server on $port", false
) {
while (!it.isCanceled && server.isRunning) {
Thread.sleep(1000)
}
if(it.isCanceled) {
log.info("Server cancelled")
server.stop()
} else {
log.info("Server stopped")
}
}
} finally {
log.info("Stopping Server")
server.stop()
}
}.start()

val server = AppServer.getServer(event.project)
val uuid = UUID.randomUUID().toString()
server.addApp("/$uuid", CodeChatServer(event.project!!, language, selectedText))
Thread {
Thread.sleep(500)
try {
Desktop.getDesktop().browse(server.uri.resolve("/index.html"))
Desktop.getDesktop().browse(server.server.uri.resolve("/$uuid/index.html"))
} catch (e: Throwable) {
log.warn("Error opening browser", e)
}
Expand Down
Loading

0 comments on commit e9d720e

Please sign in to comment.