Skip to content

Commit

Permalink
Merge pull request #8 from Kvadratni/mnovich/1.3.1
Browse files Browse the repository at this point in the history
chore: minor bugfixes
  • Loading branch information
Kvadratni authored Oct 23, 2024
2 parents d83fb55 + 1494245 commit 6dba48e
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 45 deletions.
7 changes: 5 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import org.jetbrains.intellij.platform.gradle.IntelliJPlatformType
import org.jetbrains.intellij.platform.gradle.models.ProductRelease


plugins {
id("java")
Expand All @@ -7,7 +9,7 @@ plugins {
}

group = "com.block"
version = "1.3.0"
version = "1.3.1"

repositories {
mavenCentral()
Expand All @@ -26,7 +28,7 @@ dependencies {
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
implementation("org.commonmark:commonmark:0.22.0")
intellijPlatform {
intellijIdeaUltimate("2024.1.5")
intellijIdeaUltimate("2024.2.3")
pluginVerifier()
zipSigner()
instrumentationTools()
Expand All @@ -45,6 +47,7 @@ tasks {

patchPluginXml {
sinceBuild.set("232")
untilBuild.set("250.*")
}

signPlugin {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ class GoosePluginStartupActivity : ProjectActivity {
override suspend fun execute(project: Project) {
// Check for Goose and SQ Goose availability and paths
GooseUtils.checkGooseAvailability()
GooseUtils.getAvailableProviders()
GooseUtils.getToolkitsWithDescriptions()

// Check for .goosehints file and create it if it does not exist
val gooseHintsFile = File(project.basePath, ".goosehints")
Expand Down Expand Up @@ -58,7 +60,7 @@ class GoosePluginStartupActivity : ProjectActivity {
GooseTerminalWidgetFactory().createToolWindowContent(project, toolWindow!!)
gooseTerminal = contentManager?.getContent(0)?.component as? GooseTerminalWidget
gooseTerminal?.writeToTerminal("Restarting session...")
GooseUtils.startGooseSession(true, gooseTerminal, project)
GooseUtils.startGooseSession(gooseTerminal, project)

if (!toolWindow.isVisible) {
toolWindow.activate(null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,11 @@ class SelectGooseProfileAction : AnAction() {
val yaml = Yaml()
val profiles: MutableMap<String, MutableMap<String, Any>> = yaml.load(profilesFile.readText())

val availableProviders = getAvailableProviders()
val availableProviders = GooseUtils.getAvailableProviders()

val dialog =
ProfileSelectionDialog(profiles, savedProfile, availableProviders).apply {
setSize(800, 800)
setSize(800, 800)
}
if (dialog.showAndGet()) {
val selectedProfile = dialog.getSelectedProfile()
Expand All @@ -64,14 +64,6 @@ class SelectGooseProfileAction : AnAction() {
file.writeText(yaml.dump(profiles))
}

private fun getAvailableProviders(): List<String> {
val providers = listOf("openai", "anthropic", "databricks", "ollama")
if (GooseUtils.getSqGooseState()) {
return providers + "block"
}
return providers
}


private class ProfileSelectionDialog(
private val profiles: MutableMap<String, MutableMap<String, Any>>,
Expand All @@ -81,21 +73,6 @@ class SelectGooseProfileAction : AnAction() {

private val profileList = JBList(profiles.keys.toList())
private val providerComboBox = ComboBox(availableProviders.toTypedArray())
private val toolkitToDescriptionMap: Map<String, String>
get() {
val commands = mutableListOf("goose", "toolkit", "list")
if (GooseUtils.getSqGooseState()) {
commands.add(0, GooseUtils.getSqPath())
}
val toolkitList = ProcessBuilder(commands).start()
val toolkitToDescriptionMap = mutableMapOf<String, String>()
val toolkitLines = toolkitList.inputStream.bufferedReader().readLines().drop(1)
toolkitLines.forEach {
val (name, description) = it.split(": ", limit = 2)
toolkitToDescriptionMap[name.trim().removePrefix("- ")] = description.trim()
}
return toolkitToDescriptionMap
}

private val toolkitsTableModel: DefaultTableModel =
object : DefaultTableModel(arrayOf(arrayOf("", mutableListOf<String>())), arrayOf("Toolkit", "Requires")) {
Expand All @@ -104,7 +81,8 @@ class SelectGooseProfileAction : AnAction() {
return if (columnIndex == 0) JComboBox::class.java else MultiSelectComboBox::class.java
}
}
private var toolkitComboBox: JComboBox<String> = ComboBox(toolkitToDescriptionMap.keys.toTypedArray())
private var toolkitComboBox: JComboBox<String> =
ComboBox(GooseUtils.getToolkitsWithDescriptions().keys.toTypedArray())

private val toolkitsTable = JBTable(toolkitsTableModel)
private val newProfileButton = JButton("Add New Profile")
Expand All @@ -113,7 +91,7 @@ class SelectGooseProfileAction : AnAction() {
private val saveButton = JButton("Save and Select")
private val processorComboBox = ComboBox(
arrayOf(
"gpt-4o", "claude-3-5-sonnet-20240620", "claude-3-opus-20240229", "claude-3-sonnet-20240229"
"gpt-4o", "claude-3-5-sonnet-20240620", "claude-3-opus-20240229", "claude-3-sonnet-20240229", "claude-3-5-sonnet-2"
)
)
private val acceleratorComboBox = ComboBox(arrayOf("gpt-4o-mini", "claude-3-haiku-20240307"))
Expand Down Expand Up @@ -179,7 +157,7 @@ class SelectGooseProfileAction : AnAction() {
detailPanel.add(moderatorComboBox, constraints)
val toolkitEditor = DefaultCellEditor(JComboBox(toolkitComboBox.model))
(toolkitEditor.component as JComboBox<*>).isEditable = true
val requiresEditor = MultiselectCellEditor(toolkitToDescriptionMap.keys.toTypedArray())
val requiresEditor = MultiselectCellEditor(GooseUtils.getToolkitsWithDescriptions().keys.toTypedArray())

toolkitsTable.columnModel.getColumn(0).cellEditor = toolkitEditor
toolkitsTable.columnModel.getColumn(1).cellEditor = requiresEditor
Expand Down Expand Up @@ -210,7 +188,12 @@ class SelectGooseProfileAction : AnAction() {
(profileDetails["toolkits"] as? List<Map<String, Any>>)?.associate { it["name"].toString() to (it["requires"] as? Map<String, Any>)?.keys!!.toList() }
toolkits?.forEach { (key, value) -> toolkitsTableModel.addRow(arrayOf(key, value)) }
}
toolkitsTableModel.addRow(arrayOf("", emptyList<String>())) // Add an empty row for adding new toolkits
toolkitsTableModel.addRow(
arrayOf(
"",
emptyList<String>()
)
) // Add an empty row for adding new toolkits
}

private fun addNewProfile() {
Expand All @@ -237,14 +220,35 @@ class SelectGooseProfileAction : AnAction() {
//save profile action
override fun doOKAction() {
val selectedProfile = profileList.selectedValue ?: return
providerComboBox.selectedItem?.let { profiles[selectedProfile]?.set("provider", it.toString()) }
processorComboBox.selectedItem?.let { profiles[selectedProfile]?.set("processor", it.toString()) }
acceleratorComboBox.selectedItem?.let { profiles[selectedProfile]?.set("accelerator", it.toString()) }
moderatorComboBox.selectedItem?.let { profiles[selectedProfile]?.set("moderator", it.toString()) }
providerComboBox.selectedItem?.let {
profiles[selectedProfile]?.set(
"provider",
it.toString()
)
}
processorComboBox.selectedItem?.let {
profiles[selectedProfile]?.set(
"processor",
it.toString()
)
}
acceleratorComboBox.selectedItem?.let {
profiles[selectedProfile]?.set(
"accelerator",
it.toString()
)
}
moderatorComboBox.selectedItem?.let {
profiles[selectedProfile]?.set(
"moderator",
it.toString()
)
}
val toolkitsMap = mutableListOf<Map<String, Any>>()
for (row in 0 until toolkitsTableModel.rowCount) {
val toolkit = toolkitsTableModel.getValueAt(row, 0) as String
val requiresList = (toolkitsTableModel.getValueAt(row, 1) as? Collection<String>)?.toList() ?: emptyList()
val requiresList =
(toolkitsTableModel.getValueAt(row, 1) as? Collection<String>)?.toList() ?: emptyList()
if (toolkit.isNotBlank()) {
val requiresMap = requiresList.associateWith { it }
toolkitsMap.add(mapOf("name" to toolkit, "requires" to requiresMap))
Expand Down
62 changes: 54 additions & 8 deletions src/main/kotlin/com/block/gooseintellij/utils/GooseUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,21 @@ object GooseUtils {
private var isGoosePresent: Boolean? = null
private var sqPath: String? = null
private var goosePath: String? = null
private var toolkitToDescriptionMap: MutableMap<String, String> = mutableMapOf()
private var providerList: MutableList<String> = mutableListOf()


fun writeCommandToTerminal(connector: TtyConnector, command: String) {
connector.write(command + "\r\n")
}

fun startGooseSession(usingSqGoose: Boolean, gooseTerminal: GooseTerminalWidget?, project: Project) {
fun startGooseSession(gooseTerminal: GooseTerminalWidget?, project: Project) {
val propertiesComponent = PropertiesComponent.getInstance(project)

// Load saved profile from settings
val savedProfile = propertiesComponent.getValue("goose.selected.profile")
val profileArgument = savedProfile?.let { "--profile $it" } ?: ""
val gooseInstance = if (usingSqGoose) "sq goose" else "goose"
val gooseInstance = if(getSqGooseState()) "sq goose" else "goose"
val savedSessionName = propertiesComponent.getValue("goose.saved.session")
val sessionCommand = savedSessionName?.let { "resume $it" } ?: "start"
val command = "$gooseInstance session $sessionCommand $profileArgument"
Expand All @@ -51,8 +54,8 @@ object GooseUtils {

try {
if (isGoosePresent == null) {
goosePath = getCommandOutput(arrayOf("which", "goose", "--version"))
isGoosePresent = getCommandOutput(arrayOf(goosePath!!)).isNotEmpty()
goosePath = getCommandOutput(arrayOf("which", "goose"))
isGoosePresent = getCommandOutput(arrayOf(goosePath!!, "--version")).isNotEmpty()
logger.info("Goose present: $isGoosePresent, Path: $goosePath")
}
} catch (e: Exception) {
Expand All @@ -72,10 +75,8 @@ object GooseUtils {
}

fun promptGooseInstallationIfNeeded(gooseTerminal: GooseTerminalWidget?, project: Project): Boolean {
if (isSqGoosePresent!!) {
startGooseSession(true, gooseTerminal, project)
} else if(isGoosePresent!!) {
startGooseSession(false, gooseTerminal, project)
if (getSqGooseState() || getGooseState()) {
startGooseSession(gooseTerminal, project)
} else {
ApplicationManager.getApplication().invokeLater {
val installUrl = "https://github.com/square/goose"
Expand Down Expand Up @@ -111,6 +112,10 @@ object GooseUtils {
return sqPath ?: ""
}

fun getGoosePath(): String {
return goosePath ?: ""
}

fun getShell(): Array<String> {
val command: Array<String>
val isMacOs = SystemInfo.isMac
Expand All @@ -126,4 +131,45 @@ object GooseUtils {
}
return command
}

fun getToolkitsWithDescriptions(): Map<String, String> {
if (toolkitToDescriptionMap.isNotEmpty()) {
return toolkitToDescriptionMap
}
val commands = prependGoosePath(mutableListOf("toolkit", "list"))
val toolkitList = ProcessBuilder(commands).start()
toolkitToDescriptionMap = mutableMapOf<String, String>()
val toolkitLines = toolkitList.inputStream.bufferedReader().readLines().drop(1)
toolkitLines.forEach {
val (name, description) = it.split(": ", limit = 2)
toolkitToDescriptionMap[name.trim().removePrefix("- ")] = description.trim()
}
return toolkitToDescriptionMap
}


fun getAvailableProviders(): List<String> {
if (providerList.isNotEmpty()) {
return providerList
}
val commands = prependGoosePath(mutableListOf("providers", "list"))
val providersOutput = ProcessBuilder(commands).start()
providerList = mutableListOf<String>()
val providerLines = providersOutput.inputStream.bufferedReader().readLines()
providerLines.filter { it.trim().startsWith("- ") }.forEach {
val (name) = it.split(": ", limit = 2)
providerList.add(name.trim().removePrefix("- "))
}
return providerList
}

fun prependGoosePath(commands: MutableList<String>): MutableList<String> {
if (getSqGooseState()) {
commands.add(0, getSqPath())
commands.add(1, "goose")
} else {
commands.add(0, getGoosePath())
}
return commands
}
}

0 comments on commit 6dba48e

Please sign in to comment.