From 8d4bc0b2ddc96cf863b3e9817f94003e141bf566 Mon Sep 17 00:00:00 2001 From: kami Date: Sun, 14 Jun 2026 13:28:41 +0400 Subject: [PATCH] feat(events): workflow-proposal event model ProposedWorkflow + WorkflowProposedEvent(sessionId, proposalId, prompt, candidates, originalRequest), registered in the polymorphic eventModule. Records the router's triage suggestion of candidate workflows as a non-authoritative fact the operator acts on. --- .../events/events/WorkflowProposalEvents.kt | 32 +++++++++++++++++++ .../events/serialization/Serialization.kt | 2 ++ 2 files changed, 34 insertions(+) create mode 100644 core/events/src/main/kotlin/com/correx/core/events/events/WorkflowProposalEvents.kt diff --git a/core/events/src/main/kotlin/com/correx/core/events/events/WorkflowProposalEvents.kt b/core/events/src/main/kotlin/com/correx/core/events/events/WorkflowProposalEvents.kt new file mode 100644 index 00000000..d3684133 --- /dev/null +++ b/core/events/src/main/kotlin/com/correx/core/events/events/WorkflowProposalEvents.kt @@ -0,0 +1,32 @@ +package com.correx.core.events.events + +import com.correx.core.events.types.SessionId +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * One workflow the router suggests for an operator request it cannot answer or steer directly, with + * a short [reason]. [workflowId] is one of the registered workflow ids the router was shown. + */ +@Serializable +data class ProposedWorkflow( + val workflowId: String, + val reason: String = "", +) + +/** + * The router triaged an operator request to one or more candidate workflows (option (a) of its + * triage path). Recorded as a fact (invariants #1/#9): the client renders [candidates] as a choice + * panel and, on selection, launches the chosen workflow seeded with [originalRequest] — or, via the + * panel's manual-answer slot, continues the conversation. Non-authoritative: nothing runs until the + * operator picks, so this never starts a workflow on its own. + */ +@Serializable +@SerialName("WorkflowProposed") +data class WorkflowProposedEvent( + val sessionId: SessionId, + val proposalId: String, + val prompt: String, + val candidates: List, + val originalRequest: String = "", +) : EventPayload diff --git a/core/events/src/main/kotlin/com/correx/core/events/serialization/Serialization.kt b/core/events/src/main/kotlin/com/correx/core/events/serialization/Serialization.kt index 34d2a4e6..4048567c 100644 --- a/core/events/src/main/kotlin/com/correx/core/events/serialization/Serialization.kt +++ b/core/events/src/main/kotlin/com/correx/core/events/serialization/Serialization.kt @@ -56,6 +56,7 @@ import com.correx.core.events.events.ToolInvokedEvent import com.correx.core.events.events.TransitionExecutedEvent import com.correx.core.events.events.WorkflowCompletedEvent import com.correx.core.events.events.WorkflowFailedEvent +import com.correx.core.events.events.WorkflowProposedEvent import com.correx.core.events.events.WorkflowStartedEvent import kotlinx.serialization.json.Json import kotlinx.serialization.modules.SerializersModule @@ -121,6 +122,7 @@ val eventModule = SerializersModule { subclass(HealthRestoredEvent::class) subclass(ClarificationRequestedEvent::class) subclass(ClarificationAnsweredEvent::class) + subclass(WorkflowProposedEvent::class) } }