fix(server): event capturing and necessary logic for smoke test.

This commit is contained in:
2026-05-17 03:17:12 +04:00
parent 0c1876a549
commit 7d46f46f01
39 changed files with 1097 additions and 67 deletions
@@ -0,0 +1,13 @@
package com.correx.core.artifacts.repository
import com.correx.core.artifacts.ArtifactState
import com.correx.core.events.types.ArtifactId
import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
interface ArtifactRepository {
fun getBySession(sessionId: SessionId): Map<ArtifactId, ArtifactState>
fun getByStage(sessionId: SessionId, stageId: StageId): Map<ArtifactId, ArtifactState>
fun getById(sessionId: SessionId, artifactId: ArtifactId): ArtifactState?
fun getByIds(sessionId: SessionId, artifactIds: Set<ArtifactId>): Map<ArtifactId, ArtifactState>
}
@@ -4,6 +4,7 @@ import com.correx.core.approvals.domain.ApprovalEngine
import com.correx.core.context.builder.ContextPackBuilder
import com.correx.core.inference.InferenceRouter
import com.correx.core.risk.RiskAssessor
import com.correx.core.transitions.evaluation.PromptResolver
import com.correx.core.transitions.resolution.TransitionResolver
import com.correx.core.validation.pipeline.ValidationPipeline
@@ -14,4 +15,5 @@ data class OrchestratorEngines(
val validationPipeline: ValidationPipeline,
val approvalEngine: ApprovalEngine,
val riskAssessor: RiskAssessor,
val promptResolver: PromptResolver = PromptResolver { "" },
)
@@ -1,5 +1,6 @@
package com.correx.core.kernel.orchestration
import com.correx.core.artifacts.repository.ArtifactRepository
import com.correx.core.events.stores.EventStore
import com.correx.core.inference.InferenceRepository
import com.correx.core.sessions.DefaultSessionRepository
@@ -9,4 +10,5 @@ data class OrchestratorRepositories(
val inferenceRepository: InferenceRepository,
val orchestrationRepository: OrchestrationRepository,
val sessionRepository: DefaultSessionRepository,
val artifactRepository: ArtifactRepository,
)
+1
View File
@@ -7,4 +7,5 @@ plugins {
dependencies {
implementation(project(":core:events"))
implementation(project(":core:inference"))
implementation(project(":core:artifacts"))
}
@@ -0,0 +1,8 @@
package com.correx.core.transitions.conditions
import com.correx.core.transitions.evaluation.EvaluationContext
import com.correx.core.transitions.graph.TransitionCondition
object AlwaysTrue : TransitionCondition {
override fun evaluate(context: EvaluationContext) = true
}
@@ -0,0 +1,21 @@
package com.correx.core.transitions.conditions
import com.correx.core.events.types.ArtifactId
import com.correx.core.events.types.ArtifactLifecyclePhase
import com.correx.core.transitions.evaluation.EvaluationContext
import com.correx.core.transitions.graph.TransitionCondition
data class ArtifactPresent(val artifactId: ArtifactId) : TransitionCondition {
override fun evaluate(context: EvaluationContext) =
context.artifacts[artifactId] != null
}
data class ArtifactAbsent(val artifactId: ArtifactId) : TransitionCondition {
override fun evaluate(context: EvaluationContext) =
context.artifacts[artifactId] == null
}
data class ArtifactValidated(val artifactId: ArtifactId) : TransitionCondition {
override fun evaluate(context: EvaluationContext) =
context.artifacts[artifactId]?.phase == ArtifactLifecyclePhase.VALIDATED
}
@@ -0,0 +1,19 @@
package com.correx.core.transitions.conditions
import com.correx.core.transitions.evaluation.EvaluationContext
import com.correx.core.transitions.graph.TransitionCondition
data class AllOf(val conditions: List<TransitionCondition>) : TransitionCondition {
override fun evaluate(context: EvaluationContext) =
conditions.all { it.evaluate(context) }
}
data class AnyOf(val conditions: List<TransitionCondition>) : TransitionCondition {
override fun evaluate(context: EvaluationContext) =
conditions.any { it.evaluate(context) }
}
data class Not(val condition: TransitionCondition) : TransitionCondition {
override fun evaluate(context: EvaluationContext) =
!condition.evaluate(context)
}
@@ -0,0 +1,9 @@
package com.correx.core.transitions.conditions
import com.correx.core.transitions.evaluation.EvaluationContext
import com.correx.core.transitions.graph.TransitionCondition
data class VariableEquals(val key: String, val value: String) : TransitionCondition {
override fun evaluate(context: EvaluationContext) =
context.variables[key] == value
}
@@ -1,10 +1,13 @@
package com.correx.core.transitions.evaluation
import com.correx.core.artifacts.ArtifactState
import com.correx.core.events.types.ArtifactId
import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
data class EvaluationContext(
val sessionId: SessionId,
val currentStage: StageId,
val variables: Map<String, String>
val artifacts: Map<ArtifactId, ArtifactState> = emptyMap(),
val variables: Map<String, String> = emptyMap(),
)
@@ -0,0 +1,5 @@
package com.correx.core.transitions.evaluation
fun interface PromptResolver {
fun resolve(path: String): String
}
@@ -2,7 +2,7 @@ package com.correx.core.transitions.evaluation
import com.correx.core.transitions.graph.TransitionCondition
interface TransitionConditionEvaluator {
fun interface TransitionConditionEvaluator {
fun evaluate(
condition: TransitionCondition,
context: EvaluationContext
@@ -1,5 +1,6 @@
package com.correx.core.transitions.graph
import com.correx.core.events.types.ArtifactId
import com.correx.core.inference.GenerationConfig
import com.correx.core.inference.ModelCapability
import kotlinx.serialization.Serializable
@@ -15,4 +16,7 @@ data class StageConfig(
),
val allowedTools: Set<String> = emptySet(),
val maxRetries: Int = 3,
val produces: Set<ArtifactId> = emptySet(),
val needs: Set<ArtifactId> = emptySet(),
val metadata: Map<String, String> = emptyMap(),
)
@@ -3,6 +3,7 @@ package com.correx.core.transitions.graph
import com.correx.core.events.types.StageId
data class WorkflowGraph(
val id: String = "",
val stages: Map<StageId, StageConfig>,
val transitions: Set<TransitionEdge>,
val start: StageId,
@@ -0,0 +1,159 @@
package com.correx.core.transitions.conditions
import com.correx.core.artifacts.ArtifactState
import com.correx.core.events.types.ArtifactId
import com.correx.core.events.types.ArtifactLifecyclePhase
import com.correx.core.events.types.SessionId
import com.correx.core.events.types.StageId
import com.correx.core.transitions.evaluation.EvaluationContext
import org.junit.jupiter.api.Assertions.assertFalse
import org.junit.jupiter.api.Assertions.assertTrue
import org.junit.jupiter.api.Test
class TransitionConditionTest {
private val baseContext = EvaluationContext(
sessionId = SessionId("test-session"),
currentStage = StageId("stage-1"),
)
private fun contextWith(
artifacts: Map<ArtifactId, ArtifactState> = emptyMap(),
variables: Map<String, String> = emptyMap(),
) = baseContext.copy(artifacts = artifacts, variables = variables)
// AlwaysTrue
@Test
fun `AlwaysTrue returns true`() {
assertTrue(AlwaysTrue.evaluate(baseContext))
}
// ArtifactPresent
@Test
fun `ArtifactPresent returns true when artifact in map`() {
val id = ArtifactId("a1")
val ctx = contextWith(artifacts = mapOf(id to ArtifactState()))
assertTrue(ArtifactPresent(id).evaluate(ctx))
}
@Test
fun `ArtifactPresent returns false when artifact absent`() {
val ctx = contextWith()
assertFalse(ArtifactPresent(ArtifactId("a1")).evaluate(ctx))
}
// ArtifactAbsent
@Test
fun `ArtifactAbsent returns false when artifact in map`() {
val id = ArtifactId("a1")
val ctx = contextWith(artifacts = mapOf(id to ArtifactState()))
assertFalse(ArtifactAbsent(id).evaluate(ctx))
}
@Test
fun `ArtifactAbsent returns true when artifact absent`() {
val ctx = contextWith()
assertTrue(ArtifactAbsent(ArtifactId("a1")).evaluate(ctx))
}
// ArtifactValidated
@Test
fun `ArtifactValidated returns true when phase is VALIDATED`() {
val id = ArtifactId("a1")
val ctx = contextWith(artifacts = mapOf(id to ArtifactState(phase = ArtifactLifecyclePhase.VALIDATED)))
assertTrue(ArtifactValidated(id).evaluate(ctx))
}
@Test
fun `ArtifactValidated returns false when phase is CREATED`() {
val id = ArtifactId("a1")
val ctx = contextWith(artifacts = mapOf(id to ArtifactState(phase = ArtifactLifecyclePhase.CREATED)))
assertFalse(ArtifactValidated(id).evaluate(ctx))
}
@Test
fun `ArtifactValidated returns false when phase is REJECTED`() {
val id = ArtifactId("a1")
val ctx = contextWith(artifacts = mapOf(id to ArtifactState(phase = ArtifactLifecyclePhase.REJECTED)))
assertFalse(ArtifactValidated(id).evaluate(ctx))
}
@Test
fun `ArtifactValidated returns false when artifact absent`() {
val ctx = contextWith()
assertFalse(ArtifactValidated(ArtifactId("a1")).evaluate(ctx))
}
// VariableEquals
@Test
fun `VariableEquals returns true when key matches value`() {
val ctx = contextWith(variables = mapOf("status" to "done"))
assertTrue(VariableEquals("status", "done").evaluate(ctx))
}
@Test
fun `VariableEquals returns false when key missing`() {
val ctx = contextWith()
assertFalse(VariableEquals("status", "done").evaluate(ctx))
}
@Test
fun `VariableEquals returns false when value differs`() {
val ctx = contextWith(variables = mapOf("status" to "pending"))
assertFalse(VariableEquals("status", "done").evaluate(ctx))
}
// AllOf
@Test
fun `AllOf with empty list returns true (vacuous truth)`() {
assertTrue(AllOf(emptyList()).evaluate(baseContext))
}
@Test
fun `AllOf with all true conditions returns true`() {
assertTrue(AllOf(listOf(AlwaysTrue, AlwaysTrue)).evaluate(baseContext))
}
@Test
fun `AllOf with one false condition returns false`() {
val alwaysFalse = Not(AlwaysTrue)
assertFalse(AllOf(listOf(AlwaysTrue, alwaysFalse)).evaluate(baseContext))
}
// AnyOf
@Test
fun `AnyOf with empty list returns false (vacuous falsity)`() {
assertFalse(AnyOf(emptyList()).evaluate(baseContext))
}
@Test
fun `AnyOf with one true condition returns true`() {
val alwaysFalse = Not(AlwaysTrue)
assertTrue(AnyOf(listOf(alwaysFalse, AlwaysTrue)).evaluate(baseContext))
}
@Test
fun `AnyOf with all false conditions returns false`() {
val alwaysFalse = Not(AlwaysTrue)
assertFalse(AnyOf(listOf(alwaysFalse, alwaysFalse)).evaluate(baseContext))
}
// Not
@Test
fun `Not inverts true to false`() {
assertFalse(Not(AlwaysTrue).evaluate(baseContext))
}
@Test
fun `Not inverts false to true`() {
assertTrue(Not(Not(AlwaysTrue)).evaluate(baseContext))
}
}