chore(damn): detekt, build, tests, formatting

fixed detekt issues where possible.
fixed disttar failing build because tools is added twice in the server module.
added workflowId where required.
fixed some tests not being recognized because of runBlocking without explicit return type.
formatting + imports.
This commit is contained in:
2026-05-22 00:10:05 +04:00
parent 2c459da009
commit f827685ed0
185 changed files with 1134 additions and 832 deletions
@@ -8,8 +8,8 @@ import com.correx.infrastructure.artifactscas.compact.CompactionReport
import com.correx.infrastructure.artifactscas.compact.Compactor
import com.correx.infrastructure.artifactscas.compact.LivenessScanner
import com.correx.infrastructure.artifactscas.config.CasConfig
import com.correx.infrastructure.artifactscas.evict.Evictor
import com.correx.infrastructure.artifactscas.evict.EvictionReport
import com.correx.infrastructure.artifactscas.evict.Evictor
import com.correx.infrastructure.artifactscas.index.ArtifactIndex
import com.correx.infrastructure.artifactscas.recovery.TailScanReport
import com.correx.infrastructure.artifactscas.recovery.TailScanner
@@ -3,7 +3,7 @@ package com.correx.infrastructure.artifactscas.segment
import org.bouncycastle.crypto.digests.Blake3Digest
import java.nio.ByteBuffer
import java.nio.ByteOrder
import java.util.zip.CRC32C
import java.util.zip.*
object SegmentLayout {
const val HASH_SIZE: Int = 32
@@ -24,7 +24,7 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import java.nio.file.Files
import java.nio.file.Path
import java.util.UUID
import java.util.*
import kotlin.io.path.listDirectoryEntries
class CompactorTest {
@@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.io.TempDir
import java.nio.file.Files
import java.nio.file.Path
import java.util.UUID
import java.util.*
import kotlin.io.path.listDirectoryEntries
class EvictorTest {
@@ -77,4 +77,4 @@ class InMemoryEventStore : EventStore {
return stored
}
}
}
@@ -19,7 +19,7 @@ import kotlinx.coroutines.withContext
import kotlinx.datetime.Instant
import java.sql.Connection
import java.sql.ResultSet
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.*
class SqliteEventStore(
private val connection: Connection,
@@ -254,4 +254,4 @@ private fun ResultSet.toStoredEvent(jsonSerializer: JsonEventSerializer): Stored
),
sequence = getLong("sequence"),
payload = jsonSerializer.deserialize(getString("payload"))
)
)
@@ -21,7 +21,7 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.*
class LiveArtifactRepository(
private val eventStore: EventStore,
@@ -20,4 +20,4 @@ object JDBCHelper {
autoCommit = oldAutoCommit
}
}
}
}
@@ -5,4 +5,4 @@ import com.correx.testing.contracts.fixtures.events.store.EventStoreContractTest
class InMemoryEventStoreTest : EventStoreContractTest() {
override fun store(): EventStore = InMemoryEventStore()
}
}
@@ -20,4 +20,4 @@ class InMemoryReplayTest : SessionReplayContractTest() {
SessionCounterProjection("s1")
)
}
}
}
@@ -10,4 +10,4 @@ class SqliteEventStoreTest : EventStoreContractTest() {
val conn = DriverManager.getConnection("jdbc:sqlite::memory:")
return SqliteEventStore(conn, artifactStore = NoopArtifactStore())
}
}
}
@@ -26,4 +26,4 @@ class SqliteReplayTest : SessionReplayContractTest() {
SessionCounterProjection("s1")
)
}
}
}
@@ -1,5 +1,7 @@
package com.correx.infrastructure
import com.correx.core.artifacts.DefaultArtifactReducer
import com.correx.core.artifacts.repository.ArtifactRepository
import com.correx.core.artifactstore.ArtifactStore
import com.correx.core.events.EventDispatcher
import com.correx.core.events.stores.EventStore
@@ -8,8 +10,19 @@ import com.correx.core.inference.InferenceProvider
import com.correx.core.inference.InferenceRouter
import com.correx.core.inference.ProviderRegistry
import com.correx.core.inference.RoutingStrategy
import com.correx.core.router.DefaultRouterContextBuilder
import com.correx.core.router.DefaultRouterFacade
import com.correx.core.router.DefaultRouterReducer
import com.correx.core.router.DefaultRouterRepository
import com.correx.core.router.RouterFacade
import com.correx.core.router.RouterProjector
import com.correx.core.router.model.RouterConfig
import com.correx.core.sessions.projections.replay.DefaultEventReplayer
import com.correx.core.tools.contract.ToolExecutor
import com.correx.core.tools.registry.ToolRegistry
import com.correx.infrastructure.artifactscas.CasArtifactStore
import com.correx.infrastructure.artifactscas.config.CasConfig
import com.correx.infrastructure.artifactscas.index.SqliteArtifactIndex
import com.correx.infrastructure.inference.DefaultProviderRegistry
import com.correx.infrastructure.inference.FirstAvailableRoutingStrategy
import com.correx.infrastructure.inference.commons.ModelDescriptor
@@ -17,11 +30,8 @@ import com.correx.infrastructure.inference.commons.ModelManager
import com.correx.infrastructure.inference.commons.ResidencyMode
import com.correx.infrastructure.inference.llama.cpp.DefaultModelManager
import com.correx.infrastructure.inference.llama.cpp.LlamaCppInferenceProvider
import com.correx.infrastructure.artifactscas.CasArtifactStore
import kotlinx.coroutines.runBlocking
import com.correx.infrastructure.artifactscas.config.CasConfig
import com.correx.infrastructure.artifactscas.index.SqliteArtifactIndex
import com.correx.infrastructure.persistence.SqliteEventStore
import com.correx.infrastructure.persistence.artifact.LiveArtifactRepository
import com.correx.infrastructure.tools.DefaultToolRegistry
import com.correx.infrastructure.tools.DispatchingToolExecutor
import com.correx.infrastructure.tools.SandboxedToolExecutor
@@ -31,18 +41,8 @@ import com.correx.infrastructure.workflow.FileSystemPromptLoader
import com.correx.infrastructure.workflow.PromptLoader
import com.correx.infrastructure.workflow.TomlWorkflowLoader
import com.correx.infrastructure.workflow.WorkflowLoader
import com.correx.infrastructure.persistence.artifact.LiveArtifactRepository
import com.correx.core.artifacts.repository.ArtifactRepository
import com.correx.core.artifacts.DefaultArtifactReducer
import com.correx.core.router.DefaultRouterContextBuilder
import com.correx.core.router.DefaultRouterFacade
import com.correx.core.router.DefaultRouterRepository
import com.correx.core.router.DefaultRouterReducer
import com.correx.core.router.RouterFacade
import com.correx.core.router.RouterProjector
import com.correx.core.router.model.RouterConfig
import com.correx.core.sessions.projections.replay.DefaultEventReplayer
import io.ktor.client.HttpClient
import kotlinx.coroutines.runBlocking
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.Paths
@@ -32,7 +32,7 @@ class FileReadTool(
(request.parameters["path"] as? String)?.let { pathString ->
runCatching {
val path = Paths.get(pathString).normalize().toAbsolutePath()
if (allowedPaths.isNotEmpty() && allowedPaths.none { path.startsWith(it.normalize().toAbsolutePath()) }) {
if (allowedPaths.none { path.startsWith(it.normalize().toAbsolutePath()) }) {
return@runCatching ValidationResult.Invalid("Path '$pathString' is not in the allowed list")
}
ValidationResult.Valid
@@ -65,7 +65,11 @@ class FileWriteTool(
}
put(
"required",
buildJsonArray { add(JsonPrimitive("path")); add(JsonPrimitive("content")); add(JsonPrimitive("operation")) },
buildJsonArray {
add(JsonPrimitive("path"))
add(JsonPrimitive("content"))
add(JsonPrimitive("operation"))
},
)
}
override val tier: Tier = Tier.T2
@@ -33,7 +33,7 @@ class FileEditToolTest {
}
@Test
fun `execute patch success`() = runBlocking {
fun `execute patch success`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_edit_patch")
val filePath = tempDir.resolve("test.txt")
Files.writeString(filePath, "line1\nline2\nline3\n")
@@ -63,7 +63,7 @@ class FileEditToolTest {
}
@Test
fun `validateRequest returns Invalid for disallowed path`() = runBlocking {
fun `validateRequest returns Invalid for disallowed path`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_edit_test")
val otherDir = Files.createTempDirectory("other_dir")
val tool = FileEditTool(allowedPaths = setOf(tempDir))
@@ -80,7 +80,7 @@ class FileEditToolTest {
}
@Test
fun `validateRequest returns Invalid for non-existent file`() = runBlocking {
fun `validateRequest returns Invalid for non-existent file`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_edit_test")
val tool = FileEditTool(allowedPaths = setOf(tempDir))
val request = createRequest(
@@ -96,7 +96,7 @@ class FileEditToolTest {
}
@Test
fun `validateRequest returns Invalid for missing parameters`() = runBlocking {
fun `validateRequest returns Invalid for missing parameters`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_edit_test")
val filePath = tempDir.resolve("test.txt")
Files.writeString(filePath, "content")
@@ -120,7 +120,7 @@ class FileEditToolTest {
}
@Test
fun `execute append success`() = runBlocking {
fun `execute append success`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_edit_append")
val filePath = tempDir.resolve("test.txt")
Files.writeString(filePath, "hello")
@@ -139,7 +139,7 @@ class FileEditToolTest {
}
@Test
fun `execute replace success`() = runBlocking {
fun `execute replace success`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_edit_replace")
val filePath = tempDir.resolve("test.txt")
Files.writeString(filePath, "the quick brown fox")
@@ -159,7 +159,7 @@ class FileEditToolTest {
}
@Test
fun `execute replace failure zero matches`() = runBlocking {
fun `execute replace failure zero matches`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_edit_replace_fail")
val filePath = tempDir.resolve("test.txt")
Files.writeString(filePath, "the quick brown fox")
@@ -180,7 +180,7 @@ class FileEditToolTest {
}
@Test
fun `execute replace failure multiple matches`() = runBlocking {
fun `execute replace failure multiple matches`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_edit_replace_fail_multi")
val filePath = tempDir.resolve("test.txt")
Files.writeString(filePath, "fox fox fox")
@@ -202,7 +202,7 @@ class FileEditToolTest {
@Test
fun `execute patch failure`() = runBlocking {
fun `execute patch failure`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_edit_patch_fail")
val filePath = tempDir.resolve("test.txt")
Files.writeString(filePath, "original")
@@ -31,15 +31,15 @@ class FileReadToolTest {
}
@Test
fun `validateRequest returns Valid for allowed path`() = runBlocking {
val tool = FileReadTool(allowedPaths = emptySet())
fun `validateRequest returns Valid for allowed path`(): Unit = runBlocking {
val tempFile = Files.createTempFile("test_allowed", ".txt")
val tool = FileReadTool(allowedPaths = setOf(tempFile.parent))
val request = createRequest(tempFile.toString())
assertEquals(ValidationResult.Valid, tool.validateRequest(request))
}
@Test
fun `validateRequest returns Invalid for disallowed path`() = runBlocking {
fun `validateRequest returns Invalid for disallowed path`(): Unit = runBlocking {
val tempFile = Files.createTempFile("test_disallowed", ".txt")
val tool = FileReadTool(allowedPaths = setOf(tempFile.parent.resolve("subdir")))
val request = createRequest(tempFile.toString())
@@ -49,7 +49,7 @@ class FileReadToolTest {
}
@Test
fun `validateRequest returns Invalid for missing path parameter`() = runBlocking {
fun `validateRequest returns Invalid for missing path parameter`(): Unit = runBlocking {
val tool = FileReadTool()
val request = ToolRequest(
invocationId = invocationId,
@@ -67,12 +67,12 @@ class FileReadToolTest {
}
@Test
fun `execute returns Success for valid file`() = runBlocking {
fun `execute returns Success for valid file`(): Unit = runBlocking {
val content = "Hello, world!"
val tempFile = Files.createTempFile("test_content", ".txt")
Files.writeString(tempFile, content)
val tool = FileReadTool(allowedPaths = emptySet())
val tool = FileReadTool(allowedPaths = setOf(tempFile.parent))
val request = createRequest(tempFile.toString())
val result = tool.execute(request)
@@ -83,7 +83,7 @@ class FileReadToolTest {
}
@Test
fun `execute returns Failure for non-existent file`() = runBlocking {
fun `execute returns Failure for non-existent file`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("test_dir")
val nonExistentFile = tempDir.resolve("missing.txt")
@@ -98,7 +98,7 @@ class FileReadToolTest {
}
@Test
fun `execute returns Failure for disallowed path`() = runBlocking {
fun `execute returns Failure for disallowed path`(): Unit = runBlocking {
val tempFile = Files.createTempFile("test_disallowed_exec", ".txt")
val tool = FileReadTool(allowedPaths = setOf(tempFile.parent.resolve("other")))
val request = createRequest(tempFile.toString())
@@ -34,7 +34,7 @@ class FileWriteToolTest {
}
@Test
fun `validateRequest returns Valid for allowed path and valid operation`() = runBlocking {
fun `validateRequest returns Valid for allowed path and valid operation`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_write_test")
val tool = FileWriteTool(allowedPaths = setOf(tempDir))
val request = createRequest(
@@ -48,7 +48,7 @@ class FileWriteToolTest {
}
@Test
fun `validateRequest returns Invalid for disallowed path`() = runBlocking {
fun `validateRequest returns Invalid for disallowed path`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_write_test")
val otherDir = Files.createTempDirectory("other_dir")
val tool = FileWriteTool(allowedPaths = setOf(tempDir))
@@ -65,7 +65,7 @@ class FileWriteToolTest {
}
@Test
fun `validateRequest returns Invalid for missing operation`() = runBlocking {
fun `validateRequest returns Invalid for missing operation`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_write_test")
val tool = FileWriteTool(allowedPaths = setOf(tempDir))
val request = createRequest(
@@ -83,7 +83,7 @@ class FileWriteToolTest {
}
@Test
fun `validateRequest returns Invalid for missing path`() = runBlocking {
fun `validateRequest returns Invalid for missing path`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_write_test")
val tool = FileWriteTool(allowedPaths = setOf(tempDir))
val request = createRequest(
@@ -98,7 +98,7 @@ class FileWriteToolTest {
}
@Test
fun `validateRequest returns Invalid for missing content on write`() = runBlocking {
fun `validateRequest returns Invalid for missing content on write`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_write_test")
val tool = FileWriteTool(allowedPaths = setOf(tempDir))
val request = createRequest(
@@ -113,7 +113,7 @@ class FileWriteToolTest {
}
@Test
fun `validateRequest returns Invalid for unknown operation`() = runBlocking {
fun `validateRequest returns Invalid for unknown operation`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_write_test")
val tool = FileWriteTool(allowedPaths = setOf(tempDir))
val request = createRequest(
@@ -128,7 +128,7 @@ class FileWriteToolTest {
}
@Test
fun `execute returns Success for write operation`() = runBlocking {
fun `execute returns Success for write operation`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_write_test")
val tool = FileWriteTool(allowedPaths = setOf(tempDir))
val filePath = tempDir.resolve("test.txt")
@@ -151,7 +151,7 @@ class FileWriteToolTest {
}
@Test
fun `execute returns Success for delete operation`() = runBlocking {
fun `execute returns Success for delete operation`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_write_test")
val tool = FileWriteTool(allowedPaths = setOf(tempDir))
val filePath = tempDir.resolve("to_delete.txt")
@@ -164,12 +164,7 @@ class FileWriteToolTest {
),
)
println("TempDir: $tempDir")
println("FilePath: $filePath")
println("PathString from request: ${request.parameters["path"]}")
val result = tool.execute(request)
println("Result: $result")
println("Exists after: ${Files.exists(filePath)}")
assertTrue(result is ToolResult.Success)
val success = result as ToolResult.Success
assertEquals("File deleted successfully: $filePath", success.output)
@@ -178,7 +173,7 @@ class FileWriteToolTest {
}
@Test
fun `execute returns Failure for deleting non-existent file`() = runBlocking {
fun `execute returns Failure for deleting non-existent file`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_write_test")
val tool = FileWriteTool(allowedPaths = setOf(tempDir))
val filePath = tempDir.resolve("non_existent.txt")
@@ -199,7 +194,7 @@ class FileWriteToolTest {
}
@Test
fun `execute returns Failure for disallowed path`() = runBlocking {
fun `execute returns Failure for disallowed path`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_write_test")
val otherDir = Files.createTempDirectory("other_dir")
val tool = FileWriteTool(allowedPaths = setOf(tempDir))
@@ -221,7 +216,7 @@ class FileWriteToolTest {
}
@Test
fun `validateRequest returns Valid for existing file in allowed directory`() = runBlocking {
fun `validateRequest returns Valid for existing file in allowed directory`(): Unit = runBlocking {
val tempDir = Files.createTempDirectory("file_write_test_existing")
val filePath = tempDir.resolve("existing.txt")
Files.writeString(filePath, "content")
@@ -21,7 +21,6 @@ import java.io.IOException
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardCopyOption
import java.util.*
@SuppressWarnings("TooManyFunctions", "LongParameterList")
class SandboxedToolExecutor(
@@ -1,7 +1,7 @@
package com.correx.infrastructure.tools
import com.correx.core.artifactstore.ArtifactStore
import com.correx.core.artifacts.MaterializingArtifactWriter
import com.correx.core.artifactstore.ArtifactStore
import com.correx.core.tools.contract.Tool
import com.correx.infrastructure.tools.filesystem.FileEditTool
import com.correx.infrastructure.tools.filesystem.FileReadTool
@@ -25,41 +25,55 @@ data class FileWriteConfig(
val sandboxRoot: Path? = null,
val workingDir: Path? = null,
)
data class FileEditConfig(
val enabled: Boolean = false,
val allowedPaths: Set<Path> = emptySet(),
val workingDir: Path? = null,
)
data class ShellConfig(val enabled: Boolean = false, val allowedExecutables: Set<String> = emptySet(), val workingDir: Path? = null)
data class ShellConfig(
val enabled: Boolean = false,
val allowedExecutables: Set<String> = emptySet(),
val workingDir: Path? = null,
)
/**
* Extension function to convert [ToolConfig] into a list of [Tool] implementations.
*/
fun ToolConfig.buildTools(): List<Tool> = buildList {
if (shell.enabled) {
add(ShellTool(
allowedExecutables = shell.allowedExecutables,
workingDir = shell.workingDir,
))
add(
ShellTool(
allowedExecutables = shell.allowedExecutables,
workingDir = shell.workingDir,
),
)
}
if (fileRead.enabled) {
add(FileReadTool(
allowedPaths = fileRead.allowedPaths
))
add(
FileReadTool(
allowedPaths = fileRead.allowedPaths,
),
)
}
if (fileWrite.enabled) {
add(FileWriteTool(
allowedPaths = fileWrite.allowedPaths,
artifactStore = fileWrite.artifactStore,
materializingWriter = fileWrite.materializingWriter,
sandboxRoot = fileWrite.sandboxRoot,
workingDir = fileWrite.workingDir,
))
add(
FileWriteTool(
allowedPaths = fileWrite.allowedPaths,
artifactStore = fileWrite.artifactStore,
materializingWriter = fileWrite.materializingWriter,
sandboxRoot = fileWrite.sandboxRoot,
workingDir = fileWrite.workingDir,
),
)
}
if (fileEdit.enabled) {
add(FileEditTool(
allowedPaths = fileEdit.allowedPaths,
workingDir = fileEdit.workingDir,
))
add(
FileEditTool(
allowedPaths = fileEdit.allowedPaths,
workingDir = fileEdit.workingDir,
),
)
}
}
@@ -30,14 +30,14 @@ class ShellToolTest {
}
@Test
fun `validateRequest returns Valid for allowed executable`() = runBlocking {
fun `validateRequest returns Valid for allowed executable`(): Unit = runBlocking {
val tool = ShellTool(allowedExecutables = setOf("echo"))
val request = createRequest(listOf("echo", "hello"))
assertEquals(ValidationResult.Valid, tool.validateRequest(request))
}
@Test
fun `validateRequest returns Invalid for disallowed executable`() = runBlocking {
fun `validateRequest returns Invalid for disallowed executable`(): Unit = runBlocking {
val tool = ShellTool(allowedExecutables = setOf("echo"))
val request = createRequest(listOf("ls"))
val result = tool.validateRequest(request)
@@ -46,7 +46,7 @@ class ShellToolTest {
}
@Test
fun `validateRequest returns Invalid for empty argv`() = runBlocking {
fun `validateRequest returns Invalid for empty argv`(): Unit = runBlocking {
val tool = ShellTool(allowedExecutables = setOf("echo"))
val request = createRequest(emptyList())
val result = tool.validateRequest(request)
@@ -58,7 +58,7 @@ class ShellToolTest {
}
@Test
fun `validateRequest returns Invalid for null argv`() = runBlocking {
fun `validateRequest returns Invalid for null argv`(): Unit = runBlocking {
val tool = ShellTool(allowedExecutables = setOf("echo"))
val request = ToolRequest(
invocationId = invocationId,
@@ -76,7 +76,7 @@ class ShellToolTest {
}
@Test
fun `execute returns Success for exit code 0`() = runBlocking {
fun `execute returns Success for exit code 0`(): Unit = runBlocking {
val tool = ShellTool(allowedExecutables = setOf("echo"))
val request = createRequest(listOf("echo", "hello"))
val result = tool.execute(request)
@@ -89,7 +89,7 @@ class ShellToolTest {
}
@Test
fun `execute returns Failure with non-zero exit code for failed process`() = runBlocking {
fun `execute returns Failure with non-zero exit code for failed process`(): Unit = runBlocking {
val tool = ShellTool(allowedExecutables = setOf("false"))
val request = createRequest(listOf("false"))
val result = tool.execute(request)
@@ -101,7 +101,7 @@ class ShellToolTest {
}
@Test
fun `execute returns Failure on timeout`() = runBlocking {
fun `execute returns Failure on timeout`(): Unit = runBlocking {
// Using sleep command to simulate timeout
val tool = ShellTool(allowedExecutables = setOf("sleep"), timeoutMs = 100L)
val request = createRequest(listOf("sleep", "1"))
@@ -32,12 +32,12 @@ private data class ProducesEntry(
private data class StageSection(
val id: String = "",
val prompt: String? = null,
@JsonProperty("system_prompt") val systemPrompt: String? = null,
@param:JsonProperty("system_prompt") val systemPrompt: String? = null,
val produces: List<ProducesEntry> = emptyList(),
val needs: List<String> = emptyList(),
@JsonProperty("allowed_tools") val allowedTools: List<String> = emptyList(),
@JsonProperty("token_budget") val tokenBudget: Int = 4096,
@JsonProperty("max_retries") val maxRetries: Int = 3,
@param:JsonProperty("allowed_tools") val allowedTools: List<String> = emptyList(),
@param:JsonProperty("token_budget") val tokenBudget: Int = 4096,
@param:JsonProperty("max_retries") val maxRetries: Int = 3,
)
// condition fields flattened into the transition row
@@ -45,10 +45,10 @@ private data class TransitionSection(
val id: String = "",
val from: String = "",
val to: String = "",
@JsonProperty("condition_type") val conditionType: String = "",
@JsonProperty("condition_artifact_id") val conditionArtifactId: String? = null,
@JsonProperty("condition_key") val conditionKey: String? = null,
@JsonProperty("condition_value") val conditionValue: String? = null,
@param:JsonProperty("condition_type") val conditionType: String = "",
@param:JsonProperty("condition_artifact_id") val conditionArtifactId: String? = null,
@param:JsonProperty("condition_key") val conditionKey: String? = null,
@param:JsonProperty("condition_value") val conditionValue: String? = null,
)
private const val TERMINAL = "done"
@@ -4,8 +4,8 @@ import org.junit.jupiter.api.Test
import org.junit.jupiter.api.assertThrows
import java.nio.file.Files
import kotlin.io.path.writeText
import kotlin.test.assertEquals
import kotlin.test.assertContains
import kotlin.test.assertEquals
class FileSystemPromptLoaderTest {