feat: shell execution correctness + artifact_field_equals condition

- Add  field to ProcessResultArtifact ("success"/"failed")
- Materialize ToolResult.Failure as a failed ProcessResult artifact
  in the orchestrator, with artifact lifecycle events emitted
- Non-recoverable ToolResult.Failure now fails the stage ("FATAL:")
  instead of being silently fed back as LLM context
- Fix enterStage to return Continue on non-retryable failures,
  enabling back-edge transitions (fix/retry loops)
- Add ArtifactFieldEquals transition condition with flat and
  nested dot-notation field access + FieldOperator enum
  (eq, neq, gt, gte, lt, lte)
- Wire artifact_field_equals through ConditionFactory and
  TomlWorkflowLoader (condition_field, condition_operator)
- Cache ProcessResult artifact content for evaluation context
- Add 16 tests covering all condition operators and error cases
- DefaultTransitionResolver catches condition evaluation errors
  and returns Blocked instead of crashing
This commit is contained in:
2026-05-26 17:28:51 +04:00
parent 9734eec63c
commit 3b24c7e91a
11 changed files with 304 additions and 10 deletions
@@ -4,6 +4,7 @@ import kotlinx.serialization.Serializable
@Serializable
data class ProcessResultArtifact(
val status: String = "success",
val command: String,
val exitCode: Int,
val stdout: String,
@@ -10,13 +10,14 @@ object ProcessResultKind : ArtifactKind {
override fun deriveJsonSchema(): JsonSchema = JsonSchema(
type = "object",
properties = mapOf(
"status" to JsonSchemaProperty(type = "string", description = "\"success\" or \"failed\""),
"command" to JsonSchemaProperty(type = "string"),
"exitCode" to JsonSchemaProperty(type = "integer"),
"stdout" to JsonSchemaProperty(type = "string"),
"stderr" to JsonSchemaProperty(type = "string"),
"durationMs" to JsonSchemaProperty(type = "integer"),
),
required = listOf("command", "exitCode", "stdout", "stderr", "durationMs"),
required = listOf("status", "command", "exitCode", "stdout", "stderr", "durationMs"),
additionalProperties = false,
)
}