Infer Agent from AgentPlatform by aggregate name with DefaultAgent fallback#328
Conversation
Agent-Logs-Url: https://github.com/elasticsoftwarefoundation/akces-framework/sessions/e6ed61c0-c5ac-4bbc-9cab-5e7276244968 Co-authored-by: jwijgerd <914840+jwijgerd@users.noreply.github.com>
Replace direct Agent injection in AgenticCommandHandlerFunctionAdapter and AgenticEventHandlerFunctionAdapter with runtime agent resolution based on the aggregate name. If no matching agent is found, fall back to Autonomy.chooseAndAccomplishGoal() to let Embabel decide. Remove resolveAgent() from AgenticAggregateRuntimeFactory; pass aggregate name (String) instead of Agent to adapter constructors. Agent-Logs-Url: https://github.com/elasticsoftwarefoundation/akces-framework/sessions/e6ed61c0-c5ac-4bbc-9cab-5e7276244968 Co-authored-by: jwijgerd <914840+jwijgerd@users.noreply.github.com>
Add AgenticCommandHandlerFunctionAdapterTest (12 tests) and AgenticEventHandlerFunctionAdapterTest (7 tests) covering: - Exact name match resolution - Suffix name match resolution - Autonomy chooseAndAccomplishGoal() fallback - Exception wrapping for Autonomy failures - Exact match precedence over suffix match - resolveAgentByName static helper - Basic adapter properties Agent-Logs-Url: https://github.com/elasticsoftwarefoundation/akces-framework/sessions/e6ed61c0-c5ac-4bbc-9cab-5e7276244968 Co-authored-by: jwijgerd <914840+jwijgerd@users.noreply.github.com>
…x test mocks - Narrow exception catch from generic Exception to ProcessExecutionException - Use doThrow() for Kotlin final method stubbing in tests - Provide non-null AgentProcess to ProcessExecutionFailedException constructor Agent-Logs-Url: https://github.com/elasticsoftwarefoundation/akces-framework/sessions/e6ed61c0-c5ac-4bbc-9cab-5e7276244968 Co-authored-by: jwijgerd <914840+jwijgerd@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
This PR refactors the agentic command/event handler adapters to resolve the Agent at runtime from AgentPlatform using the aggregate name, with an Autonomy.chooseAndAccomplishGoal() fallback when no matching agent is deployed. This reduces startup-time coupling to Spring bean naming and enables dynamic agent deployments.
Changes:
- Updated
AgenticCommandHandlerFunctionAdapterandAgenticEventHandlerFunctionAdapterto takeaggregateNameand resolve the agent lazily (exact or{name}Agentsuffix), with Autonomy fallback and exception wrapping. - Removed eager
Agentbean lookup fromAgenticAggregateRuntimeFactoryand passed aggregate name into adapters instead. - Added new unit tests covering agent resolution scenarios, fallback behavior, and exception wrapping.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| plans/agent-resolution-refactoring.md | Documents the refactor plan, motivation, and testing/risk notes. |
| main/agentic/src/main/java/org/elasticsoftware/akces/agentic/runtime/AgenticCommandHandlerFunctionAdapter.java | Implements runtime agent resolution + Autonomy fallback for agent-handled commands; adds helper + tick safety method. |
| main/agentic/src/main/java/org/elasticsoftware/akces/agentic/runtime/AgenticEventHandlerFunctionAdapter.java | Implements runtime agent resolution + Autonomy fallback for agent-handled external events; adds tick safety method. |
| main/agentic/src/main/java/org/elasticsoftware/akces/agentic/beans/AgenticAggregateRuntimeFactory.java | Removes eager Agent resolution and wires adapters with aggregate name instead of Agent instance. |
| main/agentic/src/test/java/org/elasticsoftware/akces/agentic/runtime/AgenticCommandHandlerFunctionAdapterTest.java | Adds unit tests for exact/suffix resolution, precedence, fallback, exception wrapping, and helper behavior. |
| main/agentic/src/test/java/org/elasticsoftware/akces/agentic/runtime/AgenticEventHandlerFunctionAdapterTest.java | Adds unit tests for exact/suffix resolution, fallback, exception wrapping, and basic adapter properties. |
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
…FunctionAdapter The code review suggestion commit introduced getAgents() which does not exist on the AgentPlatform interface. The correct method is agents(). Also restored single-pass agent resolution logic with suffix match support that was lost in the code review suggestion. Agent-Logs-Url: https://github.com/elasticsoftwarefoundation/akces-framework/sessions/e6bbbe64-67fe-4997-9046-7e96a9a43702 Co-authored-by: jwijgerd <914840+jwijgerd@users.noreply.github.com>
Fixed in f1d995e. The code review suggestion commit introduced |
jwijgerd
left a comment
There was a problem hiding this comment.
there is a javadoc issue, see: https://github.com/elasticsoftwarefoundation/akces-framework/actions/runs/24242498376/job/70780279849?pr=328
fix it so the CI build runs again
…eRuntimeFactory
The class-level javadoc still referenced {@link Agent} which was no
longer imported after agent resolution moved to the adapters. Updated
the paragraph to describe the current lazy-resolution behavior.
Agent-Logs-Url: https://github.com/elasticsoftwarefoundation/akces-framework/sessions/d46ab258-b06a-4d2a-b1ed-ccc2c1db2aae
Co-authored-by: jwijgerd <914840+jwijgerd@users.noreply.github.com>
Fixed in 1595976. The class-level javadoc in |
| aggregateName); | ||
| Autonomy autonomy = agentPlatform.getPlatformServices().autonomy(); | ||
| try { | ||
| AgentProcessExecution execution = autonomy.chooseAndAccomplishGoal( |
There was a problem hiding this comment.
in hindsight, this approach doesn't work well with the tick() approach (since the Autonomy solution runs to completion and will block the thread for a long time causing kafka to time out. Let's create a default agent that will always be present and that will be returned when no other agent matches
There was a problem hiding this comment.
Replaced the Autonomy fallback with a default agent in 9477ef6. resolveAgentByName now returns Agent directly (not Optional) — it tries exact match, then {name}Agent suffix match, then falls back to the first available agent from the platform. IllegalStateException is thrown only when no agents are deployed at all. All 63 tests pass.
The Autonomy.chooseAndAccomplishGoal() approach blocks the thread until completion, causing Kafka consumer timeouts. Replace it with a default agent fallback: when no agent matches the aggregate name (exact or suffix), the first available agent from the platform is used instead. - Remove Autonomy imports and fallback code from both adapters - Change resolveAgentByName to return Agent directly (not Optional) - Throw IllegalStateException only when no agents are deployed at all - Update tests to verify default agent and no-agents-deployed scenarios Agent-Logs-Url: https://github.com/elasticsoftwarefoundation/akces-framework/sessions/8cf48950-f35e-46f6-971b-ec135e834c54 Co-authored-by: jwijgerd <914840+jwijgerd@users.noreply.github.com>
jwijgerd
left a comment
There was a problem hiding this comment.
create a new o.e.akces.agentic.embabel package and put a class called DefaultAgent in there. Annotate with Agent and set planner field to utility. This will be the default fallback agent. We will add Actions etc later
Create a default Embabel agent annotated with @agent(planner = UTILITY) that will always be present on the AgentPlatform. This serves as the fallback agent when no other agent matches the aggregate name during agent resolution in the agentic command and event handler adapters. Agent-Logs-Url: https://github.com/elasticsoftwarefoundation/akces-framework/sessions/1a5b2b84-6e16-4eca-9184-2c6f843ddd89 Co-authored-by: jwijgerd <914840+jwijgerd@users.noreply.github.com>
Created |
…ailable agent Updated resolveAgentByName in both adapters to look specifically for the DefaultAgent by its AGENT_NAME constant instead of using the first available agent from the platform. Set name="DefaultAgent" on the @agent annotation. IllegalStateException is now thrown when no DefaultAgent is deployed (not just when no agents exist at all). Agent-Logs-Url: https://github.com/elasticsoftwarefoundation/akces-framework/sessions/16bc6db4-5f7d-4287-b643-ff758d8cf927 Co-authored-by: jwijgerd <914840+jwijgerd@users.noreply.github.com>
Refactors the agentic command/event handler adapters to resolve the
Agentat runtime fromAgentPlatformusing the aggregate name, with aDefaultAgentfallback when no matching agent is deployed. This reduces startup-time coupling to Spring bean naming and enables dynamic agent deployments.Changes Made
AgenticCommandHandlerFunctionAdapterandAgenticEventHandlerFunctionAdapterto takeaggregateNameand resolve the agent lazily (exact match or{name}Agentsuffix match), withDefaultAgentfallback when no name match is found.Agentbean lookup fromAgenticAggregateRuntimeFactoryand passed aggregate name into adapters instead.Autonomy.chooseAndAccomplishGoal()fallback — it blocks the thread until completion, causing Kafka consumer timeouts with the tick() approach. Replaced with non-blocking default agent selection.resolveAgentByNamenow returnsAgentdirectly (notOptional<Agent>), throwingIllegalStateExceptionwhen theDefaultAgentis not deployed on the platform.DefaultAgentclass inorg.elasticsoftware.akces.agentic.embabelpackage, annotated with@Agent(name = "DefaultAgent", planner = PlannerType.UTILITY). Exposes apublic static final String AGENT_NAMEconstant used by both adapters to locate the fallback agent by name. This agent is always present on theAgentPlatformvia Embabel's Spring component scanning.resolveAgentByNameexplicitly look for an agent namedDefaultAgent.AGENT_NAMEas the fallback, rather than using the first available agent from the platform.AgenticAggregateRuntimeFactory— removed stale{@link Agent}references that brokejavadoc:jar.