Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,7 @@ open class FuzzyPatchMatcher(
for (sourceLine in sourceLines) {
val patchLine = sourceLine.matchingLine ?: continue
// Skip if we've already processed this line
if (patchLine.type == DELETE || patchLine.type == ADD) continue
if (patchLine.type == ADD) continue
val pairKey = Pair(sourceLine.index, patchLine.index)
if (!processedPairs.add(pairKey)) continue

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class FuzzyPatchMatcherTest {
"/patch_add_2_lines_variant_3.json",
"/patch_inner_block.json",
"/patch_append_to_empty_file.json",
"/patch_wrap_panel.json"
)
}

Expand Down
4 changes: 2 additions & 2 deletions core/src/test/kotlin/com/simiacryptus/diff/PatchTestCase.kt
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ data class PatchTestCase(
val originalCode: String,
val diff: String,
val newCode: String,
val isValid: Boolean,
val isValid: Boolean?,
val errors: String?
) {
companion object {
Expand All @@ -18,7 +18,7 @@ data class PatchTestCase(
val stream = patcher.javaClass.getResourceAsStream(resourceName)
?: throw IllegalArgumentException("Resource not found: $resourceName")
val testCase: PatchTestCase = JsonUtil.fromJson(String(stream.readAllBytes()), PatchTestCase::class.java)
if (!testCase.isValid) return
if (false == testCase.isValid) return
val result = patcher.applyPatch(testCase.originalCode, testCase.diff)
Assertions.assertEquals(normalize(testCase.newCode), normalize(result))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,16 @@ class PythonPatchUtilTest {
fun patchTestCases() = listOf(
"/patch_exact_match.json",
"/patch_add_line.json",
"/patch_append_line.json",
"/patch_prepend_line.json",
"/patch_modify_line.json",
// "/yaml_min_repro.json",
"/patch_remove_line.json",
// "/patch_add_2_lines_variant_2.json",
// "/patch_add_2_lines_variant_3.json",
// "/patch_from_data_1.json",
// "/patch_from_data_2.json"
"/patch_inner_block.json",
"/patch_append_to_empty_file.json",
// "/patch_wrap_panel.json"
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.simiacryptus.diff

import com.simiacryptus.cognotik.diff.FuzzyPatchMatcher
import com.simiacryptus.cognotik.diff.ThermodynamicPatchMatcher
import com.simiacryptus.diff.PatchTestCase.Companion.test
import org.junit.jupiter.params.ParameterizedTest
import org.junit.jupiter.params.provider.MethodSource

class ThermodynamicPatchMatcherTest {

companion object {
@JvmStatic
fun testCases() = listOf(
"/patch_exact_match.json",
"/patch_add_line.json",
"/patch_append_line.json",
"/patch_prepend_line.json",
"/patch_modify_line.json",
"/yaml_min_repro.json",
"/patch_remove_line.json",
// "/patch_add_2_lines_variant_2.json",
// "/patch_add_2_lines_variant_3.json",
// "/patch_inner_block.json",
// "/patch_append_to_empty_file.json",
// "/patch_wrap_panel.json"
)
}

@ParameterizedTest
@MethodSource("testCases")
fun testPatchApplication(resourceName: String) {
test(resourceName, ThermodynamicPatchMatcher())
}

}

7 changes: 7 additions & 0 deletions core/src/test/resources/patch_wrap_panel.json

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
pluginName=Cognotik - Open Source Agentic Power Tools
pluginRepositoryUrl=https://github.com/SimiaCryptus/Cognotik
libraryGroup=com.simiacryptus
libraryVersion=2.0.32
libraryVersion=2.0.33
# Maven Central Publishing
cognotikGroup=com.cognotik
cognotikVersion=2.0.32
cognotikVersion=2.0.33
# Signing (set these in ~/.gradle/gradle.properties or as environment variables)
# signing.keyId=<last 8 chars of key>
# signing.password=<key password>
Expand Down
40 changes: 24 additions & 16 deletions intellij/src/main/kotlin/cognotik/actions/plan/PlanConfigDialog.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import com.intellij.openapi.ui.ComboBox
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.openapi.ui.Messages
import com.intellij.ui.components.JBList
import com.intellij.ui.components.JBScrollPane
import com.intellij.ui.components.JBTextField
import com.intellij.ui.dsl.builder.Align
import com.intellij.ui.dsl.builder.panel
import com.simiacryptus.cognotik.chat.model.ChatModel
import com.simiacryptus.cognotik.config.AppSettingsState
import com.simiacryptus.cognotik.models.AIModel
Expand Down Expand Up @@ -97,7 +97,7 @@ class PlanConfigDialog(
settings.defaultModel?.model?.modelName ?: AppSettingsState.instance.smartModel?.model?.modelName
toolTipText = "Default AI model for all tasks"
}
private val parsingModelCombo =
private val parsingModelCombo =
ComboBox(visibleModelsCache.distinctBy { it.modelName }.map { it.modelName }.toTypedArray()).apply {
maximumSize = Dimension(CONFIG_COMBO_WIDTH, CONFIG_COMBO_HEIGHT)
selectedItem =
Expand Down Expand Up @@ -130,10 +130,11 @@ private val parsingModelCombo =

// Task configuration list
private val taskConfigListModel = DefaultListModel<TaskConfigEntry>()
private val taskConfigList = JBList(taskConfigListModel).apply {
private val taskConfigList = JBList(taskConfigListModel).apply {
cellRenderer = TaskConfigListCellRenderer()
selectionMode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
toolTipText = "Configured tasks - double-click to edit"
visibleRowCount = 2
}


Expand Down Expand Up @@ -222,7 +223,7 @@ private val taskConfigList = JBList(taskConfigListModel).apply {
if (dialog.showAndGet()) {
val selectedTaskTypes = dialog.getSelectedTaskTypes()
if (selectedTaskTypes.isEmpty()) return

// If multiple tasks selected, use default configuration without opening edit dialog
if (selectedTaskTypes.size > 1) {
selectedTaskTypes.forEach { taskType ->
Expand Down Expand Up @@ -464,7 +465,7 @@ private val taskConfigList = JBList(taskConfigListModel).apply {
settings.temperature = config.temperature.coerceIn(0.0, 1.0)
settings.autoFix = config.autoFix
settings.maxTaskHistoryChars = config.maxTaskHistoryChars
settings.maxTasksPerIteration = config.maxTasksPerIteration
settings.maxTasksPerIteration = config.maxTasksPerIteration
settings.maxIterations = config.maxIterations
settings.defaultModel = config.defaultModel
settings.parsingModel = config.parsingModel
Expand Down Expand Up @@ -502,7 +503,7 @@ settings.maxTasksPerIteration = config.maxTasksPerIteration
}
}

config.parsingModel?.model?.modelName?.let { modelName ->
config.parsingModel?.model?.modelName?.let { modelName ->
visibleModelsCache.find { it.modelName == modelName }?.let { model ->
settings.parsingModel = model.toApiChatModel()
parsingModelCombo.selectedItem = modelName
Expand All @@ -523,7 +524,8 @@ config.parsingModel?.model?.modelName?.let { modelName ->
}
}

override fun createCenterPanel(): JComponent = panel {

override fun createCenterPanel(): JComponent = JBScrollPane(com.intellij.ui.dsl.builder.panel {
group {
row("Saved Configs:") {
cell(savedConfigsCombo).align(Align.FILL)
Expand Down Expand Up @@ -562,7 +564,6 @@ config.parsingModel?.model?.modelName?.let { modelName ->
button("Copy") { exportTaskConfigs() }
button("Paste") { importTaskConfigs() }
}

group("Planning Settings") {
row("Cognitive Mode:") {
cell(cognitiveModeCombo).align(Align.FILL).comment("Select the cognitive strategy for planning")
Expand All @@ -571,12 +572,10 @@ config.parsingModel?.model?.modelName?.let { modelName ->
cell(autoPlanPanel).align(Align.FILL)
}
}

row {
cell(autoFixCheckbox).align(Align.FILL)
.comment("Automatically apply suggested fixes without confirmation")
}

row("Temperature:") {
cell(temperatureSlider).align(Align.FILL)
.comment("Adjust AI response creativity (higher = more creative)")
Expand All @@ -586,23 +585,22 @@ config.parsingModel?.model?.modelName?.let { modelName ->
cell(globalModelCombo).align(Align.FILL)
.comment("Default AI model for all tasks")
}
row("Parsing Model:") {
row("Parsing Model:") {
cell(parsingModelCombo).align(Align.FILL)
.comment("AI model for parsing and understanding tasks")
}
row("Image Chat Model:") {
cell(imageChatModelCombo).align(Align.FILL)
.comment("Multimodal AI model for image-related tasks")
}

group("Task Configurations") {
row {
scrollCell(taskConfigList)
.align(Align.FILL)
.comment("Double-click to edit a task configuration")
.resizableColumn()
}.resizableRow()
row {
row {
button("Add Task Config") {
addTaskConfig()
}
Expand Down Expand Up @@ -630,13 +628,23 @@ row {
}
}
}

}
}).apply {
border = null
viewport.border = null
horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER
}


override fun doOKAction() {
updateSettings() ?: return
try {
val configs = AppSettingsState.instance.savedPlanConfigs ?: mutableMapOf()
configs["Last"] = toJson(settings)
AppSettingsState.instance.savedPlanConfigs = configs
} catch (e: Exception) {
log.warn("Failed to save 'Last' configuration", e)
}
super.doOKAction()
}

Expand Down Expand Up @@ -665,7 +673,7 @@ row {
val model = visibleModelsCache.find { it.modelName == selectedGlobalModel }
settings.defaultModel = model?.toApiChatModel()
}
val selectedParsingModel = parsingModelCombo.selectedItem as? String
val selectedParsingModel = parsingModelCombo.selectedItem as? String
if (selectedParsingModel != null) {
val model = visibleModelsCache.find { it.modelName == selectedParsingModel }
settings.parsingModel = model?.toApiChatModel()
Expand Down Expand Up @@ -707,7 +715,7 @@ val selectedParsingModel = parsingModelCombo.selectedItem as? String
// Validation patterns
private val CONFIG_NAME_PATTERN = Regex("^[a-zA-Z0-9_ -]+$")

fun isVisible(chatModel: AIModel) =
fun isVisible(chatModel: AIModel) =
ApplicationServices.fileApplicationServices().userSettingsManager.getUserSettings().apis.filter { it.key != null }
.any { it.provider == chatModel.provider }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import com.intellij.openapi.ui.ComboBox
import com.intellij.openapi.ui.DialogWrapper
import com.intellij.openapi.ui.Messages
import com.intellij.ui.components.JBList
import com.intellij.ui.components.JBScrollPane
import com.intellij.ui.components.JBTextArea
import com.intellij.ui.components.JBTextField
import com.intellij.ui.dsl.builder.Align
Expand Down Expand Up @@ -52,37 +53,48 @@ class TaskConfigEditDialog(

// For SubPlanning task settings
private val subTaskConfigListModel = DefaultListModel<SubTaskConfigEntry>()
private val subTaskConfigList = JBList(subTaskConfigListModel)
private val subTaskConfigList = JBList(subTaskConfigListModel).apply {
this.visibleRowCount = 2
}

init {
init()
title = "Edit ${taskType.name} Configuration"
isResizable = true
}
override fun getDimensionServiceKey(): String = "TaskConfigEditDialog"

override fun createCenterPanel(): JComponent = panel {
group("Task Configuration") {
row("Configuration Name:") {
cell(configNameField)
.align(Align.FILL)
.comment("Enter a unique name for this configuration")

override fun createCenterPanel(): JComponent {
val dialogPanel = panel {
group("Task Configuration") {
row("Configuration Name:") {
cell(configNameField)
.align(Align.FILL)
.comment("Enter a unique name for this configuration")
}

row("AI Model:") {
cell(modelCombo)
.align(Align.FILL)
.comment("Select the AI model to use for this task type")
}
}
// Add task-specific configuration fields
createTaskSpecificFields()

row("AI Model:") {
cell(modelCombo)
.align(Align.FILL)
.comment("Select the AI model to use for this task type")
group("Task Type Information") {
row {
text(taskType.description ?: "No description available")
}
}
}
// Add task-specific configuration fields
createTaskSpecificFields()

group("Task Type Information") {
row {
text(taskType.description ?: "No description available")
}
return JBScrollPane(dialogPanel).apply {
preferredSize = Dimension(900, 700)
border = BorderFactory.createEmptyBorder()
horizontalScrollBarPolicy = ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED
}
}.apply {
preferredSize = Dimension(600, 500)
}

private fun com.intellij.ui.dsl.builder.Panel.createTaskSpecificFields() {
Expand Down Expand Up @@ -286,13 +298,17 @@ class TaskConfigEditDialog(
)
return
}
val configDialog = TaskConfigEditDialog(null, taskType, newConfig, availableModels)
if (configDialog.showAndGet()) {
val config = configDialog.getConfig()
val key = if (config.name != null) "${taskType.name}_${config.name}" else taskType.name
parentConfig.taskSettings[key] = config
subTaskConfigListModel.addElement(SubTaskConfigEntry(taskType, config, key))

val config = if (dialog.isQuickSelect) {
newConfig
} else {
val configDialog = TaskConfigEditDialog(null, taskType, newConfig, availableModels)
if (configDialog.showAndGet()) configDialog.getConfig() else return
}

val key = if (config.name != null) "${taskType.name}_${config.name}" else taskType.name
parentConfig.taskSettings[key] = config
subTaskConfigListModel.addElement(SubTaskConfigEntry(taskType, config, key))
}
}

Expand Down
Loading
Loading