chore(clean up): remove unused imports, unnecessary object impls, concurrency/coroutine issues, trailing commas, etc.
This commit is contained in:
@@ -132,20 +132,24 @@ class RunCommand : CliktCommand(name = "run") {
|
|||||||
setExitCode(0)
|
setExitCode(0)
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
"SessionFailed" -> {
|
"SessionFailed" -> {
|
||||||
val reason = field("reason") ?: "unknown"
|
val reason = field("reason") ?: "unknown"
|
||||||
printLine("session_failed", mapOf("sessionId" to ctx.sid, "reason" to reason), ctx.outputJson)
|
printLine("session_failed", mapOf("sessionId" to ctx.sid, "reason" to reason), ctx.outputJson)
|
||||||
setExitCode(1)
|
setExitCode(1)
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
"StageStarted" -> {
|
"StageStarted" -> {
|
||||||
printLine("stage_started", mapOf("stageId" to (field("stageId") ?: "")), ctx.outputJson)
|
printLine("stage_started", mapOf("stageId" to (field("stageId") ?: "")), ctx.outputJson)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
"StageCompleted" -> {
|
"StageCompleted" -> {
|
||||||
printLine("stage_completed", mapOf("stageId" to (field("stageId") ?: "")), ctx.outputJson)
|
printLine("stage_completed", mapOf("stageId" to (field("stageId") ?: "")), ctx.outputJson)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
"StageFailed" -> {
|
"StageFailed" -> {
|
||||||
printLine(
|
printLine(
|
||||||
"stage_failed",
|
"stage_failed",
|
||||||
@@ -154,14 +158,17 @@ class RunCommand : CliktCommand(name = "run") {
|
|||||||
)
|
)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
"ToolStarted" -> {
|
"ToolStarted" -> {
|
||||||
printLine("tool_started", mapOf("tool" to (field("toolName") ?: "")), ctx.outputJson)
|
printLine("tool_started", mapOf("tool" to (field("toolName") ?: "")), ctx.outputJson)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
"ToolCompleted" -> {
|
"ToolCompleted" -> {
|
||||||
printLine("tool_completed", mapOf("tool" to (field("toolName") ?: "")), ctx.outputJson)
|
printLine("tool_completed", mapOf("tool" to (field("toolName") ?: "")), ctx.outputJson)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
"ToolFailed" -> {
|
"ToolFailed" -> {
|
||||||
printLine(
|
printLine(
|
||||||
"tool_failed",
|
"tool_failed",
|
||||||
@@ -170,6 +177,7 @@ class RunCommand : CliktCommand(name = "run") {
|
|||||||
)
|
)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
"ToolRejected" -> {
|
"ToolRejected" -> {
|
||||||
printLine(
|
printLine(
|
||||||
"tool_rejected",
|
"tool_rejected",
|
||||||
@@ -178,6 +186,7 @@ class RunCommand : CliktCommand(name = "run") {
|
|||||||
)
|
)
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
"ApprovalRequired" -> {
|
"ApprovalRequired" -> {
|
||||||
val approvalCtx = ApprovalContext(
|
val approvalCtx = ApprovalContext(
|
||||||
session = session,
|
session = session,
|
||||||
@@ -187,6 +196,7 @@ class RunCommand : CliktCommand(name = "run") {
|
|||||||
)
|
)
|
||||||
handleApproval(approvalCtx, ctx, setExitCode)
|
handleApproval(approvalCtx, ctx, setExitCode)
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -200,7 +210,7 @@ class RunCommand : CliktCommand(name = "run") {
|
|||||||
|
|
||||||
val steeringNote = if (decision == "STEER" && ctx.isTty) {
|
val steeringNote = if (decision == "STEER" && ctx.isTty) {
|
||||||
print("Steering note: ")
|
print("Steering note: ")
|
||||||
readLine()
|
readlnOrNull()
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@@ -225,10 +235,11 @@ class RunCommand : CliktCommand(name = "run") {
|
|||||||
ctx.autoApprove -> "APPROVE"
|
ctx.autoApprove -> "APPROVE"
|
||||||
!ctx.isTty -> {
|
!ctx.isTty -> {
|
||||||
System.err.println(
|
System.err.println(
|
||||||
"WARNING: approval required but no TTY and --auto-approve not set — denying"
|
"WARNING: approval required but no TTY and --auto-approve not set — denying",
|
||||||
)
|
)
|
||||||
"REJECT"
|
"REJECT"
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> promptApproval(toolName, preview)
|
else -> promptApproval(toolName, preview)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -236,7 +247,7 @@ class RunCommand : CliktCommand(name = "run") {
|
|||||||
println("\nApproval required for tool: $toolName")
|
println("\nApproval required for tool: $toolName")
|
||||||
preview?.let { println("Preview: $it") }
|
preview?.let { println("Preview: $it") }
|
||||||
print("[a]pprove / [r]eject / [s]teer: ")
|
print("[a]pprove / [r]eject / [s]teer: ")
|
||||||
return when (readLine()?.trim()?.lowercase()) {
|
return when (readlnOrNull()?.trim()?.lowercase()) {
|
||||||
"a", "approve" -> "APPROVE"
|
"a", "approve" -> "APPROVE"
|
||||||
"s", "steer" -> "STEER"
|
"s", "steer" -> "STEER"
|
||||||
else -> "REJECT"
|
else -> "REJECT"
|
||||||
@@ -256,4 +267,4 @@ class RunCommand : CliktCommand(name = "run") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class SystemExitException(val code: Int) : Exception("exit $code")
|
class SystemExitException(code: Int) : Exception("exit $code")
|
||||||
|
|||||||
@@ -67,8 +67,9 @@ class SessionEventBridgeTest {
|
|||||||
override suspend fun appendAll(events: List<NewEvent>): List<StoredEvent> = error("unused")
|
override suspend fun appendAll(events: List<NewEvent>): List<StoredEvent> = error("unused")
|
||||||
override fun read(sessionId: SessionId): List<StoredEvent> = allEventsList
|
override fun read(sessionId: SessionId): List<StoredEvent> = allEventsList
|
||||||
override fun readFrom(sessionId: SessionId, fromSequence: Long): List<StoredEvent> = allEventsList
|
override fun readFrom(sessionId: SessionId, fromSequence: Long): List<StoredEvent> = allEventsList
|
||||||
override fun lastSequence(sessionId: SessionId): Long? =
|
override fun lastSequence(sessionId: SessionId): Long =
|
||||||
allEventsList.maxOfOrNull { it.sequence } ?: 0L
|
allEventsList.maxOfOrNull { it.sequence } ?: 0L
|
||||||
|
|
||||||
override fun subscribe(sessionId: SessionId): Flow<StoredEvent> = liveFlow
|
override fun subscribe(sessionId: SessionId): Flow<StoredEvent> = liveFlow
|
||||||
override fun allEvents(): Sequence<StoredEvent> = allEventsList.asSequence()
|
override fun allEvents(): Sequence<StoredEvent> = allEventsList.asSequence()
|
||||||
override fun allSessionIds(): Set<SessionId> = allEventsList.map { it.metadata.sessionId }.toSet()
|
override fun allSessionIds(): Set<SessionId> = allEventsList.map { it.metadata.sessionId }.toSet()
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ fun main(args: Array<String>) {
|
|||||||
log.debug("got input state after reducers: {}", next.input)
|
log.debug("got input state after reducers: {}", next.input)
|
||||||
log.debug(
|
log.debug(
|
||||||
"got session state after reducers: {}",
|
"got session state after reducers: {}",
|
||||||
next.sessions.sessions.firstOrNull() { it.status != "COMPLETED" },
|
next.sessions.sessions.firstOrNull { it.status != "COMPLETED" },
|
||||||
)
|
)
|
||||||
state = next
|
state = next
|
||||||
effects.forEach { effect ->
|
effects.forEach { effect ->
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ private fun createRowsForNavigate(
|
|||||||
hasSession: Boolean,
|
hasSession: Boolean,
|
||||||
): Pair<Line?, Line?> {
|
): Pair<Line?, Line?> {
|
||||||
val row1Line = Line.from(Span.styled(" ↑↓ sessions enter select", dimStyle))
|
val row1Line = Line.from(Span.styled(" ↑↓ sessions enter select", dimStyle))
|
||||||
val hints = buildList<String> {
|
val hints = buildList {
|
||||||
add("$sessionName · navigate")
|
add("$sessionName · navigate")
|
||||||
add("tab router")
|
add("tab router")
|
||||||
if (hasApproval) {
|
if (hasApproval) {
|
||||||
@@ -96,7 +96,7 @@ private fun createRowsForRouter(
|
|||||||
} else {
|
} else {
|
||||||
Line.from(Span.raw("▌ "), Span.styled("Ask anything…", dimStyle))
|
Line.from(Span.raw("▌ "), Span.styled("Ask anything…", dimStyle))
|
||||||
}
|
}
|
||||||
val hints = buildList<String> {
|
val hints = buildList {
|
||||||
add("$sessionName · router")
|
add("$sessionName · router")
|
||||||
add("tab navigate")
|
add("tab navigate")
|
||||||
if (hasApproval) {
|
if (hasApproval) {
|
||||||
|
|||||||
+9
-8
@@ -142,10 +142,7 @@ abstract class SessionOrchestrator(
|
|||||||
?.let { path ->
|
?.let { path ->
|
||||||
runCatching { promptResolver.resolve(path) }
|
runCatching { promptResolver.resolve(path) }
|
||||||
.onFailure {
|
.onFailure {
|
||||||
log.error(
|
log.error(error(stageId, path, it))
|
||||||
"[SessionOrchestrator] stage=${stageId.value}: " +
|
|
||||||
"failed to load prompt '$path': ${it.message}",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
.getOrNull()
|
.getOrNull()
|
||||||
}
|
}
|
||||||
@@ -165,10 +162,7 @@ abstract class SessionOrchestrator(
|
|||||||
?.let { path ->
|
?.let { path ->
|
||||||
runCatching { promptResolver.resolve(path) }
|
runCatching { promptResolver.resolve(path) }
|
||||||
.onFailure {
|
.onFailure {
|
||||||
log.error(
|
log.error(error(stageId, path, it))
|
||||||
"[SessionOrchestrator] stage=${stageId.value}: " +
|
|
||||||
"failed to load default system prompt '$path': ${it.message}",
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
.getOrNull()
|
.getOrNull()
|
||||||
}
|
}
|
||||||
@@ -275,6 +269,13 @@ abstract class SessionOrchestrator(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun error(
|
||||||
|
stageId: StageId,
|
||||||
|
path: String,
|
||||||
|
throwable: Throwable,
|
||||||
|
): String = "[SessionOrchestrator] stage=${stageId.value}: " +
|
||||||
|
"failed to load prompt '$path': ${throwable.message}"
|
||||||
|
|
||||||
private suspend fun dispatchToolCalls(
|
private suspend fun dispatchToolCalls(
|
||||||
sessionId: SessionId,
|
sessionId: SessionId,
|
||||||
stageId: StageId,
|
stageId: StageId,
|
||||||
|
|||||||
+2
-1
@@ -7,6 +7,7 @@ import com.correx.core.artifacts.kind.FileWrittenPayload
|
|||||||
import com.correx.infrastructure.artifactscas.segment.SegmentLayout
|
import com.correx.infrastructure.artifactscas.segment.SegmentLayout
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@@ -15,7 +16,7 @@ import java.nio.file.attribute.PosixFilePermissions
|
|||||||
class DefaultMaterializingArtifactWriter : MaterializingArtifactWriter {
|
class DefaultMaterializingArtifactWriter : MaterializingArtifactWriter {
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
val log = LoggerFactory.getLogger(DefaultMaterializingArtifactWriter::class.java)
|
val log: Logger = LoggerFactory.getLogger(DefaultMaterializingArtifactWriter::class.java)
|
||||||
const val DEFAULT_MODE = "644"
|
const val DEFAULT_MODE = "644"
|
||||||
const val OCTAL_RADIX = 8
|
const val OCTAL_RADIX = 8
|
||||||
const val POSIX_PERMISSION_BITS = 9
|
const val POSIX_PERMISSION_BITS = 9
|
||||||
|
|||||||
+15
-13
@@ -37,21 +37,23 @@ class TailScanner(
|
|||||||
private suspend fun scanAndRecover(activeId: Long, path: Path, startOffset: Long): TailScanReport {
|
private suspend fun scanAndRecover(activeId: Long, path: Path, startOffset: Long): TailScanReport {
|
||||||
var recovered = 0
|
var recovered = 0
|
||||||
var truncatedAt: Long? = null
|
var truncatedAt: Long? = null
|
||||||
RandomAccessFile(path.toFile(), "rw").use { raf ->
|
withContext(Dispatchers.IO) {
|
||||||
val fileLen = raf.length()
|
RandomAccessFile(path.toFile(), "rw").use { raf ->
|
||||||
var pos = startOffset
|
val fileLen = raf.length()
|
||||||
while (pos < fileLen) {
|
var pos = startOffset
|
||||||
val step = tryReadRecord(raf, pos, fileLen)
|
while (pos < fileLen) {
|
||||||
if (step == null) {
|
val step = tryReadRecord(raf, pos, fileLen)
|
||||||
truncatedAt = pos
|
if (step == null) {
|
||||||
break
|
truncatedAt = pos
|
||||||
|
break
|
||||||
|
}
|
||||||
|
index.insert(step.hash, Location(activeId, pos, step.length))
|
||||||
|
recovered += 1
|
||||||
|
pos += SegmentLayout.HEADER_SIZE + step.length
|
||||||
}
|
}
|
||||||
index.insert(step.hash, Location(activeId, pos, step.length))
|
// Truncate at first bad/partial record so writer resumes at a clean boundary.
|
||||||
recovered += 1
|
truncatedAt?.let { raf.setLength(it) }
|
||||||
pos += SegmentLayout.HEADER_SIZE + step.length
|
|
||||||
}
|
}
|
||||||
// Truncate at first bad/partial record so writer resumes at a clean boundary.
|
|
||||||
truncatedAt?.let { raf.setLength(it) }
|
|
||||||
}
|
}
|
||||||
return TailScanReport(activeId, startOffset, recovered, truncatedAt)
|
return TailScanReport(activeId, startOffset, recovered, truncatedAt)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-3
@@ -25,7 +25,7 @@ import java.util.concurrent.*
|
|||||||
|
|
||||||
class LiveArtifactRepository(
|
class LiveArtifactRepository(
|
||||||
private val eventStore: EventStore,
|
private val eventStore: EventStore,
|
||||||
private val reducer: ArtifactReducer,
|
reducer: ArtifactReducer,
|
||||||
private val scope: CoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()),
|
private val scope: CoroutineScope = CoroutineScope(Dispatchers.IO + SupervisorJob()),
|
||||||
) : ArtifactRepository {
|
) : ArtifactRepository {
|
||||||
|
|
||||||
@@ -41,8 +41,8 @@ class LiveArtifactRepository(
|
|||||||
|
|
||||||
override fun getByStage(sessionId: SessionId, stageId: StageId): Map<ArtifactId, ArtifactState> {
|
override fun getByStage(sessionId: SessionId, stageId: StageId): Map<ArtifactId, ArtifactState> {
|
||||||
ensureSubscribed(sessionId)
|
ensureSubscribed(sessionId)
|
||||||
val cache = artifactCache[sessionId] ?: emptyMap<ArtifactId, ArtifactState>()
|
val cache = artifactCache[sessionId] ?: emptyMap()
|
||||||
val index = stageIndex[sessionId] ?: emptyMap<ArtifactId, StageId>()
|
val index = stageIndex[sessionId] ?: emptyMap()
|
||||||
return cache.filter { (artifactId, _) -> index[artifactId] == stageId }
|
return cache.filter { (artifactId, _) -> index[artifactId] == stageId }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-3
@@ -24,6 +24,7 @@ import kotlinx.serialization.json.buildJsonArray
|
|||||||
import kotlinx.serialization.json.buildJsonObject
|
import kotlinx.serialization.json.buildJsonObject
|
||||||
import kotlinx.serialization.json.put
|
import kotlinx.serialization.json.put
|
||||||
import kotlinx.serialization.json.putJsonObject
|
import kotlinx.serialization.json.putJsonObject
|
||||||
|
import org.slf4j.Logger
|
||||||
import org.slf4j.LoggerFactory
|
import org.slf4j.LoggerFactory
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
@@ -40,7 +41,7 @@ class FileWriteTool(
|
|||||||
) : Tool, FileAffectingTool, ToolExecutor {
|
) : Tool, FileAffectingTool, ToolExecutor {
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
val log = LoggerFactory.getLogger(FileWriteTool::class.java)
|
val log: Logger = LoggerFactory.getLogger(FileWriteTool::class.java)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val normalizedAllowedPaths: Set<Path> = allowedPaths.map { it.normalize().toAbsolutePath() }.toSet()
|
private val normalizedAllowedPaths: Set<Path> = allowedPaths.map { it.normalize().toAbsolutePath() }.toSet()
|
||||||
@@ -172,7 +173,9 @@ class FileWriteTool(
|
|||||||
): ToolResult = when (operation) {
|
): ToolResult = when (operation) {
|
||||||
"write" -> {
|
"write" -> {
|
||||||
val content = request.parameters["content"] as String
|
val content = request.parameters["content"] as String
|
||||||
Files.writeString(path, content)
|
withContext(Dispatchers.IO) {
|
||||||
|
Files.writeString(path, content)
|
||||||
|
}
|
||||||
storeArtifact(pathString, content, request.parameters["mode"] as? String ?: "0644")
|
storeArtifact(pathString, content, request.parameters["mode"] as? String ?: "0644")
|
||||||
ToolResult.Success(
|
ToolResult.Success(
|
||||||
invocationId = request.invocationId,
|
invocationId = request.invocationId,
|
||||||
@@ -182,7 +185,9 @@ class FileWriteTool(
|
|||||||
|
|
||||||
"delete" -> {
|
"delete" -> {
|
||||||
if (Files.exists(path)) {
|
if (Files.exists(path)) {
|
||||||
Files.deleteIfExists(path)
|
withContext(Dispatchers.IO) {
|
||||||
|
Files.deleteIfExists(path)
|
||||||
|
}
|
||||||
ToolResult.Success(
|
ToolResult.Success(
|
||||||
invocationId = request.invocationId,
|
invocationId = request.invocationId,
|
||||||
output = "File deleted successfully: $pathString",
|
output = "File deleted successfully: $pathString",
|
||||||
|
|||||||
+1
-1
@@ -145,7 +145,7 @@ class FileWriteToolTest {
|
|||||||
|
|
||||||
assertTrue(result is ToolResult.Success)
|
assertTrue(result is ToolResult.Success)
|
||||||
val success = result as ToolResult.Success
|
val success = result as ToolResult.Success
|
||||||
assertEquals("File written successfully to ${filePath}", success.output)
|
assertEquals("File written successfully to $filePath", success.output)
|
||||||
assertEquals(invocationId, success.invocationId)
|
assertEquals(invocationId, success.invocationId)
|
||||||
assertEquals(content, Files.readString(filePath))
|
assertEquals(content, Files.readString(filePath))
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-14
@@ -31,20 +31,22 @@ class DefaultInferenceRouterTest {
|
|||||||
override fun register(provider: InferenceProvider) = Unit
|
override fun register(provider: InferenceProvider) = Unit
|
||||||
override fun resolve(capability: ModelCapability) =
|
override fun resolve(capability: ModelCapability) =
|
||||||
providers.filter { p -> p.capabilities().any { it.capability == capability } }
|
providers.filter { p -> p.capabilities().any { it.capability == capability } }
|
||||||
|
|
||||||
override fun listAll() = providers.toList()
|
override fun listAll() = providers.toList()
|
||||||
override suspend fun healthCheckAll() = providers.associate { it.id to ProviderHealth.Healthy }
|
override suspend fun healthCheckAll() = providers.associate { it.id to ProviderHealth.Healthy }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun firstStrategy(): RoutingStrategy =
|
private fun firstStrategy(): RoutingStrategy =
|
||||||
object : RoutingStrategy {
|
RoutingStrategy { candidates, _ ->
|
||||||
override fun select(candidates: List<InferenceProvider>, requiredCapabilities: Set<ModelCapability>) =
|
candidates.firstOrNull() ?: throw NoEligibleProviderException(StageId("?"), emptySet())
|
||||||
candidates.firstOrNull() ?: throw NoEligibleProviderException(StageId("?"), emptySet())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun throwingStrategy(): RoutingStrategy =
|
private fun throwingStrategy(): RoutingStrategy =
|
||||||
object : RoutingStrategy {
|
RoutingStrategy { _, requiredCapabilities ->
|
||||||
override fun select(candidates: List<InferenceProvider>, requiredCapabilities: Set<ModelCapability>) =
|
throw NoEligibleProviderException(
|
||||||
throw NoEligibleProviderException(StageId("?"), requiredCapabilities)
|
StageId("?"),
|
||||||
|
requiredCapabilities,
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ── capability matching ───────────────────────────────────────────────────
|
// ── capability matching ───────────────────────────────────────────────────
|
||||||
@@ -60,14 +62,9 @@ class DefaultInferenceRouterTest {
|
|||||||
fun `deduplicates providers that satisfy multiple required capabilities`(): Unit = runBlocking {
|
fun `deduplicates providers that satisfy multiple required capabilities`(): Unit = runBlocking {
|
||||||
val p = provider("a", ModelCapability.General, ModelCapability.Coding)
|
val p = provider("a", ModelCapability.General, ModelCapability.Coding)
|
||||||
val selected = mutableListOf<InferenceProvider>()
|
val selected = mutableListOf<InferenceProvider>()
|
||||||
val captureStrategy = object : RoutingStrategy {
|
val captureStrategy = RoutingStrategy { candidates, _ ->
|
||||||
override fun select(
|
selected.addAll(candidates)
|
||||||
candidates: List<InferenceProvider>,
|
candidates.first()
|
||||||
requiredCapabilities: Set<ModelCapability>,
|
|
||||||
): InferenceProvider {
|
|
||||||
selected.addAll(candidates)
|
|
||||||
return candidates.first()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
val router = DefaultInferenceRouter(
|
val router = DefaultInferenceRouter(
|
||||||
registryOf(p),
|
registryOf(p),
|
||||||
|
|||||||
+3
-4
@@ -7,7 +7,6 @@ import com.correx.core.events.types.SessionId
|
|||||||
import com.correx.testing.contracts.utils.ConcurrencyRunner
|
import com.correx.testing.contracts.utils.ConcurrencyRunner
|
||||||
import com.correx.testing.fixtures.EventFixtures
|
import com.correx.testing.fixtures.EventFixtures
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.flow.collect
|
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
import kotlinx.coroutines.yield
|
import kotlinx.coroutines.yield
|
||||||
@@ -39,7 +38,7 @@ abstract class EventStoreContractTest {
|
|||||||
|
|
||||||
store.append(e)
|
store.append(e)
|
||||||
assertThrows<Exception> {
|
assertThrows<Exception> {
|
||||||
runBlocking { store.append(e) }
|
store.append(e)
|
||||||
}
|
}
|
||||||
Assertions.assertEquals(1, store.read(SessionId("s1")).size)
|
Assertions.assertEquals(1, store.read(SessionId("s1")).size)
|
||||||
}
|
}
|
||||||
@@ -75,7 +74,7 @@ abstract class EventStoreContractTest {
|
|||||||
ConcurrencyRunner.run(20, 100) { t, i ->
|
ConcurrencyRunner.run(20, 100) { t, i ->
|
||||||
runBlocking {
|
runBlocking {
|
||||||
store.append(
|
store.append(
|
||||||
EventFixtures.newEvent(EventId("e-$i-$t"), SessionId("s1"))
|
EventFixtures.newEvent(EventId("e-$i-$t"), SessionId("s1")),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,7 +151,7 @@ abstract class EventStoreContractTest {
|
|||||||
store.append(EventFixtures.newEvent(EventId("a-$t-$i"), SessionId("s1")))
|
store.append(EventFixtures.newEvent(EventId("a-$t-$i"), SessionId("s1")))
|
||||||
} else {
|
} else {
|
||||||
store.appendAll(
|
store.appendAll(
|
||||||
listOf(EventFixtures.newEvent(EventId("b-$t-$i"), SessionId("s1")))
|
listOf(EventFixtures.newEvent(EventId("b-$t-$i"), SessionId("s1"))),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import com.correx.core.events.events.EventMetadata
|
import com.correx.core.events.events.EventMetadata
|
||||||
import com.correx.core.events.events.EventPayload
|
|
||||||
import com.correx.core.events.events.NewEvent
|
import com.correx.core.events.events.NewEvent
|
||||||
import com.correx.core.events.events.SessionPausedEvent
|
import com.correx.core.events.events.SessionPausedEvent
|
||||||
import com.correx.core.events.events.SessionResumedEvent
|
import com.correx.core.events.events.SessionResumedEvent
|
||||||
@@ -20,7 +19,7 @@ class SessionReplayDeterminismTest {
|
|||||||
|
|
||||||
private fun build(store: EventStore) = DefaultEventReplayer(
|
private fun build(store: EventStore) = DefaultEventReplayer(
|
||||||
store,
|
store,
|
||||||
SessionProjector(DefaultSessionReducer())
|
SessionProjector(DefaultSessionReducer()),
|
||||||
)
|
)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -30,16 +29,16 @@ class SessionReplayDeterminismTest {
|
|||||||
val store1 = InMemoryEventStore()
|
val store1 = InMemoryEventStore()
|
||||||
val store2 = InMemoryEventStore()
|
val store2 = InMemoryEventStore()
|
||||||
|
|
||||||
val events = mapOf<EventMetadata, EventPayload>(
|
val events = mapOf(
|
||||||
EventMetadata(EventId("start"), sessionId, Clock.System.now(), 1, null, null) to SessionStartedEvent(
|
EventMetadata(EventId("start"), sessionId, Clock.System.now(), 1, null, null) to SessionStartedEvent(
|
||||||
sessionId
|
sessionId,
|
||||||
),
|
),
|
||||||
EventMetadata(EventId("paused"), sessionId, Clock.System.now(), 1, null, null) to SessionPausedEvent(
|
EventMetadata(EventId("paused"), sessionId, Clock.System.now(), 1, null, null) to SessionPausedEvent(
|
||||||
sessionId
|
sessionId,
|
||||||
),
|
),
|
||||||
EventMetadata(EventId("resumed"), sessionId, Clock.System.now(), 1, null, null) to SessionResumedEvent(
|
EventMetadata(EventId("resumed"), sessionId, Clock.System.now(), 1, null, null) to SessionResumedEvent(
|
||||||
sessionId
|
sessionId,
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
events.forEach { (meta, payload) ->
|
events.forEach { (meta, payload) ->
|
||||||
|
|||||||
+1
-7
@@ -2,10 +2,8 @@ package com.correx.testing.fixtures.transitions
|
|||||||
|
|
||||||
import com.correx.core.events.types.StageId
|
import com.correx.core.events.types.StageId
|
||||||
import com.correx.core.events.types.TransitionId
|
import com.correx.core.events.types.TransitionId
|
||||||
import com.correx.core.transitions.evaluation.EvaluationContext
|
|
||||||
import com.correx.core.transitions.evaluation.TransitionConditionEvaluator
|
import com.correx.core.transitions.evaluation.TransitionConditionEvaluator
|
||||||
import com.correx.core.transitions.graph.StageConfig
|
import com.correx.core.transitions.graph.StageConfig
|
||||||
import com.correx.core.transitions.graph.TransitionCondition
|
|
||||||
import com.correx.core.transitions.graph.TransitionEdge
|
import com.correx.core.transitions.graph.TransitionEdge
|
||||||
import com.correx.core.transitions.graph.WorkflowGraph
|
import com.correx.core.transitions.graph.WorkflowGraph
|
||||||
import com.correx.core.transitions.resolution.DefaultTransitionResolver
|
import com.correx.core.transitions.resolution.DefaultTransitionResolver
|
||||||
@@ -15,11 +13,7 @@ import com.correx.testing.fixtures.WorkflowFixtures
|
|||||||
object TransitionFixtures {
|
object TransitionFixtures {
|
||||||
|
|
||||||
fun alwaysTrueEvaluator(): TransitionConditionEvaluator {
|
fun alwaysTrueEvaluator(): TransitionConditionEvaluator {
|
||||||
return object : TransitionConditionEvaluator {
|
return TransitionConditionEvaluator { _, _ -> true }
|
||||||
override fun evaluate(condition: TransitionCondition, context: EvaluationContext): Boolean {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun simpleResolver(): TransitionResolver {
|
fun simpleResolver(): TransitionResolver {
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import com.correx.core.events.events.EventMetadata
|
import com.correx.core.events.events.EventMetadata
|
||||||
import com.correx.core.events.events.EventPayload
|
|
||||||
import com.correx.core.events.events.NewEvent
|
import com.correx.core.events.events.NewEvent
|
||||||
import com.correx.core.events.events.SessionCompletedEvent
|
import com.correx.core.events.events.SessionCompletedEvent
|
||||||
import com.correx.core.events.events.SessionPausedEvent
|
import com.correx.core.events.events.SessionPausedEvent
|
||||||
@@ -26,15 +25,15 @@ class SessionReplayTest {
|
|||||||
fun `rebuild session from event stream`(): Unit = kotlinx.coroutines.runBlocking {
|
fun `rebuild session from event stream`(): Unit = kotlinx.coroutines.runBlocking {
|
||||||
val sessionId = SessionId("s1")
|
val sessionId = SessionId("s1")
|
||||||
|
|
||||||
val metadataToPayload = mapOf<EventMetadata, EventPayload>(
|
val metadataToPayload = mapOf(
|
||||||
EventMetadata(EventId("start"), sessionId, Clock.System.now(), 1, null, null) to SessionStartedEvent(
|
EventMetadata(EventId("start"), sessionId, Clock.System.now(), 1, null, null) to SessionStartedEvent(
|
||||||
sessionId
|
sessionId,
|
||||||
),
|
),
|
||||||
EventMetadata(EventId("paused"), sessionId, Clock.System.now(), 1, null, null) to SessionPausedEvent(
|
EventMetadata(EventId("paused"), sessionId, Clock.System.now(), 1, null, null) to SessionPausedEvent(
|
||||||
sessionId
|
sessionId,
|
||||||
),
|
),
|
||||||
EventMetadata(EventId("resumed"), sessionId, Clock.System.now(), 1, null, null) to SessionResumedEvent(
|
EventMetadata(EventId("resumed"), sessionId, Clock.System.now(), 1, null, null) to SessionResumedEvent(
|
||||||
sessionId
|
sessionId,
|
||||||
),
|
),
|
||||||
EventMetadata(
|
EventMetadata(
|
||||||
EventId("completed"),
|
EventId("completed"),
|
||||||
@@ -42,7 +41,7 @@ class SessionReplayTest {
|
|||||||
Clock.System.now(),
|
Clock.System.now(),
|
||||||
1,
|
1,
|
||||||
null,
|
null,
|
||||||
null
|
null,
|
||||||
) to SessionCompletedEvent(sessionId),
|
) to SessionCompletedEvent(sessionId),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -16,14 +16,7 @@ import org.junit.jupiter.api.assertInstanceOf
|
|||||||
|
|
||||||
class DefaultTransitionResolverTest {
|
class DefaultTransitionResolverTest {
|
||||||
|
|
||||||
private val evaluator = object : TransitionConditionEvaluator {
|
private val evaluator = TransitionConditionEvaluator { condition, context -> condition.evaluate(context) }
|
||||||
override fun evaluate(
|
|
||||||
condition: TransitionCondition,
|
|
||||||
context: EvaluationContext,
|
|
||||||
): Boolean {
|
|
||||||
return condition.evaluate(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val resolver: TransitionResolver = DefaultTransitionResolver(evaluator)
|
private val resolver: TransitionResolver = DefaultTransitionResolver(evaluator)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user