Class AgentRuleDispatcher
agentic.Rule configurations and dispatches the configured AI agent for each match,
posting the agent's analysis back where the event happened (a task comment, when the event
carries a task) and recording every firing in the run history.
A rule without a flow is advise-only: the analysis lands as a comment. A rule with
a flow classifies the agent's answer into the author's outcome vocabulary and executes the
matched branch's actions (AgentRuleFlow) — each action isolated, each carrying its own
autonomy mode: auto executes immediately; propose parks an AgentRuleProposal for
one-click human approval, and executeApproved(com.xebialabs.xlrelease.agentrules.AgentRuleProposal, java.lang.String, java.lang.String) runs it attributed to the approver.
Rules are ordinary shared configurations, so authoring needs no restart: the rule set is cached and invalidated on any configuration change event. A rule's optional conditions (folder prefix, release-title pattern, task type, tags) are AND-ed; empty conditions match.
Design constraints this class must respect (structural, not stylistic):
- The event bus swallows handler exceptions, so every failure here surfaces itself explicitly: agent-call failures become a short comment on the task and a failed run in the history, never silence.
@AsyncSubscribehandlers share the bus's default executor, so the handler only filters and captures, then hands the slow agent round trip (an LLM turn — minutes, not millis) to this feature's own executor.- Events fire on the node that owns the release actor, which gives exactly-once dispatch in a cluster for free.
- Failure storms must not become agent storms: a per-rule-per-entity debounce, a per-release run budget, and a per-rule circuit breaker (consecutive agent failures pause the rule) cap the blast radius.
- All outbound policy lives in the gateway: the A2A feature toggle and agent
allowlist are enforced by
A2aAgentGateway, so a rule cannot reach a non-allowlisted agent by construction. - No feedback loops: the comments this class writes are system comments
(null author), and
CommentCreatedEvents without an author are never matched against rules.
Everything read from a CI attached to an event is copied to plain strings before the
executor hand-off — the event's Task/Release are not thread-safe and must not
cross threads.
-
Constructor Summary
ConstructorsConstructorDescriptionAgentRuleDispatcher(com.xebialabs.xlrelease.events.XLReleaseEventBus eventBus, org.springframework.beans.factory.ObjectProvider<com.xebialabs.xlrelease.a2a.api.A2aAgentGateway> gatewayProvider, com.xebialabs.xlrelease.service.CommentService commentService, com.xebialabs.xlrelease.repository.ConfigurationRepository configurationRepository, com.xebialabs.xlrelease.config.XlrConfig xlrConfig, AgentRuleRunStore runStore, AgentRuleProposalStore proposalStore, com.xebialabs.xlrelease.actors.ReleaseActorService releaseActorService, com.xebialabs.xlrelease.repository.ReleaseRepository releaseRepository, com.xebialabs.xlrelease.service.VariableService variableService, AgentRuleTokenService tokenService, ExecutorService executor) -
Method Summary
Modifier and TypeMethodDescriptionexecuteApproved(AgentRuleProposal proposal, String username, String subjectToken) Executes a proposal a human just approved.voidonConfigurationChanged(com.xebialabs.xlrelease.domain.events.ConfigurationEvent event) Any configuration change may be a rule change; the snapshot is cheap to rebuild lazily.voidonEvent(com.xebialabs.xlrelease.domain.events.XLReleaseEvent event) voidvoid
-
Constructor Details
-
AgentRuleDispatcher
public AgentRuleDispatcher(com.xebialabs.xlrelease.events.XLReleaseEventBus eventBus, org.springframework.beans.factory.ObjectProvider<com.xebialabs.xlrelease.a2a.api.A2aAgentGateway> gatewayProvider, com.xebialabs.xlrelease.service.CommentService commentService, com.xebialabs.xlrelease.repository.ConfigurationRepository configurationRepository, com.xebialabs.xlrelease.config.XlrConfig xlrConfig, AgentRuleRunStore runStore, AgentRuleProposalStore proposalStore, com.xebialabs.xlrelease.actors.ReleaseActorService releaseActorService, com.xebialabs.xlrelease.repository.ReleaseRepository releaseRepository, com.xebialabs.xlrelease.service.VariableService variableService, AgentRuleTokenService tokenService, ExecutorService executor)
-
-
Method Details
-
subscribe
@PostConstruct public void subscribe() -
unsubscribe
@PreDestroy public void unsubscribe() -
onConfigurationChanged
public void onConfigurationChanged(com.xebialabs.xlrelease.domain.events.ConfigurationEvent event) Any configuration change may be a rule change; the snapshot is cheap to rebuild lazily. -
onEvent
public void onEvent(com.xebialabs.xlrelease.domain.events.XLReleaseEvent event) -
executeApproved
Executes a proposal a human just approved. Called on the approver's request thread, so the ambient authenticated identity is the approver — retry/skip are attributed to them, which is exactly the audit trail an approval should leave. The slow delegation action is the one exception: it is handed to this feature's executor and reports back as a comment.- Parameters:
subjectToken- the approver's own access token (nullable), captured on their request thread; when the RFC 8693 exchange is configured, the delegated agent then runs on the approver's identity instead of the service account- Returns:
- a short human-readable result for the approval response
-