fix(server): event capturing and necessary logic for smoke test.
This commit is contained in:
+13
@@ -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>
|
||||
}
|
||||
+2
@@ -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 { "" },
|
||||
)
|
||||
|
||||
+2
@@ -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,
|
||||
)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
+21
@@ -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)
|
||||
}
|
||||
+9
@@ -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
|
||||
}
|
||||
+4
-1
@@ -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(),
|
||||
)
|
||||
+5
@@ -0,0 +1,5 @@
|
||||
package com.correx.core.transitions.evaluation
|
||||
|
||||
fun interface PromptResolver {
|
||||
fun resolve(path: String): String
|
||||
}
|
||||
+1
-1
@@ -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,
|
||||
|
||||
+159
@@ -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))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user