Skip to content

Commit be79dfa

Browse files
committed
wip
1 parent 1f95135 commit be79dfa

File tree

13 files changed

+1004
-155
lines changed

13 files changed

+1004
-155
lines changed

Code:

Lines changed: 0 additions & 92 deletions
This file was deleted.

README.1.md

Lines changed: 0 additions & 1 deletion
This file was deleted.

core/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ dependencies {
4747
implementation(libs.jackson.kotlin)
4848
implementation(libs.jackson.jaxrs.json)
4949
implementation(libs.jackson.datatype.jsr310)
50+
implementation(libs.jackson.datatype.jdk8)
5051
testImplementation(project(":jo-penai"))
5152

5253

core/src/main/kotlin/com/simiacryptus/cognotik/util/JsonUtil.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import com.fasterxml.jackson.core.JsonToken
66
import com.fasterxml.jackson.core.json.JsonReadFeature
77
import com.fasterxml.jackson.databind.DeserializationFeature
88
import com.fasterxml.jackson.databind.JavaType
9+
import com.fasterxml.jackson.databind.MapperFeature
910
import com.fasterxml.jackson.databind.ObjectMapper
1011
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
1112
import com.fasterxml.jackson.module.kotlin.KotlinFeature
@@ -28,6 +29,7 @@ object JsonUtil {
2829
.enable(JsonParser.Feature.ALLOW_COMMENTS)
2930
.enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES)
3031
.enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES)
32+
.disable(MapperFeature.REQUIRE_HANDLERS_FOR_JAVA8_OPTIONALS)
3133
.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
3234
.disable(DeserializationFeature.FAIL_ON_IGNORED_PROPERTIES)
3335
.disable(DeserializationFeature.FAIL_ON_MISSING_CREATOR_PROPERTIES)

gradle/libs.versions.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ jackson-annotations = { group = "com.fasterxml.jackson.core", name = "jackson-an
8888
jackson-kotlin = { group = "com.fasterxml.jackson.module", name = "jackson-module-kotlin", version.ref = "jackson" }
8989
jackson-jaxrs-json = { group = "com.fasterxml.jackson.jaxrs", name = "jackson-jaxrs-json-provider", version.ref = "jackson" }
9090
jackson-datatype-jsr310 = { group = "com.fasterxml.jackson.datatype", name = "jackson-datatype-jsr310", version.ref = "jackson" }
91+
jackson-datatype-jdk8 = { group = "com.fasterxml.jackson.datatype", name = "jackson-datatype-jdk8", version.ref = "jackson" }
9192
aws-sdk = { group = "software.amazon.awssdk", name = "aws-sdk-java", version.ref = "aws" }
9293
aws-bedrock = { group = "software.amazon.awssdk", name = "bedrock", version.ref = "aws" }
9394
aws-bedrockruntime = { group = "software.amazon.awssdk", name = "bedrockruntime", version.ref = "aws" }

webapp/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
"concurrently": "^9.1.2",
6666
"cross-env": "^7.0.3",
6767
"eslint-plugin-react-hooks": "^4.6.0",
68-
"sass": "^1.94.2",
68+
"sass": "^1.96.0",
6969
"typescript": "^4.9.5"
7070
},
7171
"eslintConfig": {

webui/src/main/kotlin/com/simiacryptus/cognotik/apps/general/PatchApp.kt

Lines changed: 44 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ abstract class PatchApp(
5858
private var lastParsedErrors: ParsedErrors? = null
5959

6060
private val previousParsedErrorsRecords = mutableListOf<ParsedErrorRecord>()
61+
data class FixAttempt(val error: String, val patch: String, val timestamp: Long = System.currentTimeMillis())
62+
private val fixHistory = mutableMapOf<String, MutableList<FixAttempt>>()
6163

6264
abstract fun codeFiles(): Set<Path>
6365

@@ -134,10 +136,9 @@ abstract class PatchApp(
134136
override val inputCnt = 1
135137
override val stickyInput = false
136138
override fun newSession(user: User, session: Session): SocketManager {
137-
val socketManager = super.newSession(user, session)
139+
val ui = super.newSession(user, session)
138140
log.info("Creating new session for user: ${user?.id ?: "anonymous"}")
139141
var retries: Int = -1
140-
val ui = socketManager
141142
val task = ui.newTask()
142143
var retryOnOffButton: StringBuilder? = null
143144
val disableButton = task.hrefLink("Disable Auto-Retry") {
@@ -159,7 +160,7 @@ abstract class PatchApp(
159160
}
160161
log.debug("Initialized retries to $retries")
161162
}
162-
val newTask = ui.newTask(false)
163+
val newTask = task.linkedTask("Run Command${if (retries < settings.maxRetries) " (Retry ${settings.maxRetries - retries}/$settings.maxRetries)" else ""}")
163164
Thread {
164165
log.info("Starting run thread")
165166
val model = model.getChildClient(task)
@@ -174,7 +175,7 @@ abstract class PatchApp(
174175
newTask.placeholder
175176
}
176177
log.info("Session setup complete")
177-
return socketManager
178+
return ui
178179
}
179180

180181
abstract fun projectSummary(): String
@@ -307,7 +308,6 @@ abstract class PatchApp(
307308
task = fixTask,
308309
plan = plan,
309310
settings = settings,
310-
changed = mutableSetOf(),
311311
progressHeader = progressHeader,
312312
model = model
313313
)
@@ -330,12 +330,10 @@ abstract class PatchApp(
330330
task: SessionTask,
331331
plan: ParsedResponse<ParsedErrors>,
332332
settings: Settings,
333-
changed: MutableSet<Path>,
334333
progressHeader: StringBuilder?,
335334
model: ChatInterface
336335
) {
337336
log.info("Starting fixAllErrors")
338-
val tabs = TabbedDisplay(task)
339337
val errors = plan.obj.errors ?: emptyList()
340338
val hasErrors = errors.any { it.isWarning != true }
341339
log.info("Found ${errors.size} errors, hasErrors=$hasErrors")
@@ -351,24 +349,30 @@ abstract class PatchApp(
351349
.map { (msg, errors) ->
352350
log.info("Processing error group: $msg with ${errors.size} instances")
353351
task.ui.pool.submit {
354-
val task = task.ui.newTask(false).apply { tabs[msg ?: "Error"] = placeholder }
352+
val subSession = task.linkedTask("Fix: ${msg?.take(50) ?: "Error"}...")
353+
val statusBuffer = subSession.add("Status: Initializing...")!!
355354
errors.forEach { error ->
356355
log.info("Processing individual error: ${error.message}")
357-
task.header("Processing error: $msg", 3)
358-
task.add(
356+
statusBuffer.set("Status: Analyzing error details...")
357+
subSession.update()
358+
359+
subSession.header("Processing error: $msg", 3)
360+
subSession.add(
359361
renderMarkdown(
360362
"```json\n${JsonUtil.toJson(error)}\n```",
361363
tabs = false,
362-
ui = task.ui
364+
ui = subSession.ui
363365
)
364366
)
365-
task.verbose(
367+
subSession.verbose(
366368
renderMarkdown(
367369
"[Extra Details] Error processed at: ${Instant.now()}",
368370
tabs = false,
369-
ui = task.ui
371+
ui = subSession.ui
370372
)
371373
)
374+
statusBuffer.set("Status: Searching for relevant files...")
375+
subSession.update()
372376

373377
val searchResults = error.research?.searchQueries?.flatMap { query ->
374378
log.debug("Executing search query: pattern=${query.pattern}, glob=${query.fileGlob}")
@@ -383,22 +387,25 @@ abstract class PatchApp(
383387
}?.toSet() ?: emptySet()
384388
log.info("Search found ${searchResults.size} relevant files")
385389
if (searchResults.isNotEmpty()) {
386-
task.verbose(
390+
subSession.verbose(
387391
renderMarkdown(
388392
"Search results:\n\n${searchResults.joinToString("\n") { "* `$it`" }}",
389393
tabs = false,
390-
ui = task.ui
394+
ui = subSession.ui
391395
)
392396
)
393397
}
398+
statusBuffer.set("Status: Generating fix...")
399+
subSession.update()
394400
fix(
395401
error,
396402
searchResults.toList().map { it.toFile().absolutePath },
397403
settings.autoFix,
398-
changed,
399-
task,
404+
subSession,
400405
model
401406
)
407+
statusBuffer.set("Status: Complete")
408+
subSession.update()
402409
}
403410
}
404411
}.toTypedArray().onEach { it.get() }
@@ -472,7 +479,6 @@ abstract class PatchApp(
472479
error: ParsedError,
473480
additionalFiles: List<String>? = null,
474481
autoFix: Boolean,
475-
changed: MutableSet<Path>,
476482
task: SessionTask,
477483
model: ChatInterface,
478484
) {
@@ -508,6 +514,15 @@ abstract class PatchApp(
508514

509515
val summary = codeSummary(prunedPaths.distinct(), error)
510516
log.info("Generated code summary (${summary.length} chars)")
517+
val historyContext = prunedPaths.mapNotNull { path ->
518+
val history = fixHistory[path.toString()]
519+
if (!history.isNullOrEmpty()) {
520+
"### History for `$path`\n" + history.joinToString("\n") {
521+
"- [${SimpleDateFormat("HH:mm:ss").format(it.timestamp)}] Attempted fix for '${it.error}'"
522+
} + "\n\nPrevious patches applied to this file:\n```diff\n" + history.joinToString("\n\n") { it.patch } + "\n```"
523+
} else null
524+
}.joinToString("\n\n")
525+
511526
val fixResponse = ChatAgent(
512527
prompt = """
513528
You are a helpful AI that helps people with coding.
@@ -522,31 +537,31 @@ abstract class PatchApp(
522537
listOf(
523538
"$promptPrefix\n\nFocus on and Fix the Error:\n ${error.message ?: ""}\n" +
524539
(if (error.details?.isNotBlank() == true) "Details:\n ${error.details}\n" else "") +
525-
(if (settings.additionalInstructions.isNotBlank()) "Additional Instructions:\n ${settings.additionalInstructions}\n" else "")
540+
(if (settings.additionalInstructions.isNotBlank()) "Additional Instructions:\n ${settings.additionalInstructions}\n" else "") +
541+
(if (historyContext.isNotBlank()) "\n\nPrevious Debugging Attempts (Learn from these):\n$historyContext" else "")
526542
),
527543

528544
).lines().joinToString("\n") {
529545
it.replace(Regex("""/\* Error.*?\*/"""), "")
530546
}
531547
log.info("Received fix response (${fixResponse.length} chars)")
548+
// Record history
549+
prunedPaths.forEach { path ->
550+
fixHistory.getOrPut(path.toString()) { mutableListOf() }.add(
551+
FixAttempt(error.message ?: "Unknown", fixResponse)
552+
)
553+
}
554+
532555
val markdown = AddApplyFileDiffLinks.instrumentFileDiffs(
533556
self = task.ui,
534557
root = root.toPath(),
535558
response = fixResponse,
536559
shouldAutoApply = { path ->
537-
if (autoFix && !changed.contains(path)) {
560+
if (autoFix) {
538561
log.info("Auto-applying fix to: $path")
539-
changed.add(path)
540562
true
541563
} else {
542-
log.debug(
543-
"Not auto-applying fix to: {} (autoFix={}, already changed={})",
544-
path,
545-
autoFix,
546-
changed.contains(
547-
path
548-
)
549-
)
564+
log.debug("Not auto-applying fix to: {} (autoFix={})", path, autoFix)
550565
false
551566
}
552567
},

0 commit comments

Comments
 (0)