Migration Guide: 0.4.x to 0.5.0¶
Module Changes¶
The single spring-ai-agent-utils module has been split into three:
| New Module | Description |
|---|---|
spring-ai-agent-utils-common |
Shared subagent SPI (interfaces & records) |
spring-ai-agent-utils |
Core library (tools, skills, Claude subagents) |
spring-ai-agent-utils-a2a |
A2A protocol subagent implementation |
spring-ai-agent-utils-bom |
Bill of Materials for version management |
Add spring-ai-agent-utils-common as a transitive dependency (pulled in automatically by the core module). Add spring-ai-agent-utils-a2a only if you use A2A subagents:
<dependency>
<groupId>org.springaicommunity</groupId>
<artifactId>spring-ai-agent-utils-a2a</artifactId>
<version>0.5.0-SNAPSHOT</version>
</dependency>
Package Relocations¶
The subagent SPI types moved from org.springaicommunity.agent.tools.task.subagent to org.springaicommunity.agent.common.task.subagent:
| Old Import | New Import |
|---|---|
o.s.agent.tools.task.subagent.SubagentDefinition |
o.s.agent.common.task.subagent.SubagentDefinition |
o.s.agent.tools.task.subagent.SubagentExecutor |
o.s.agent.common.task.subagent.SubagentExecutor |
o.s.agent.tools.task.subagent.SubagentResolver |
o.s.agent.common.task.subagent.SubagentResolver |
o.s.agent.tools.task.subagent.SubagentReference |
o.s.agent.common.task.subagent.SubagentReference |
o.s.agent.tools.task.subagent.SubagentType |
o.s.agent.common.task.subagent.SubagentType |
o.s.agent.tools.task.TaskTool.TaskCall |
o.s.agent.common.task.subagent.TaskCall |
Claude-specific classes moved up one level (the intermediate subagent package was removed):
| Old Import | New Import |
|---|---|
o.s.agent.tools.task.subagent.claude.ClaudeSubagentDefinition |
o.s.agent.tools.task.claude.ClaudeSubagentDefinition |
o.s.agent.tools.task.subagent.claude.ClaudeSubagentExecutor |
o.s.agent.tools.task.claude.ClaudeSubagentExecutor |
o.s.agent.tools.task.subagent.claude.ClaudeSubagentReferences |
o.s.agent.tools.task.claude.ClaudeSubagentReferences |
o.s.agent.tools.task.subagent.claude.ClaudeSubagentResolver |
o.s.agent.tools.task.claude.ClaudeSubagentResolver |
o.s.agent.tools.task.subagent.claude.ClaudeSubagentType |
o.s.agent.tools.task.claude.ClaudeSubagentType |
A2A classes moved from the example package to the new module:
| Old Import | New Import |
|---|---|
o.s.agent.a2a.A2ASubagentDefinition |
o.s.agent.subagent.a2a.A2ASubagentDefinition |
o.s.agent.a2a.A2ASubagentExecutor |
o.s.agent.subagent.a2a.A2ASubagentExecutor |
o.s.agent.a2a.A2ASubagentResolver |
o.s.agent.subagent.a2a.A2ASubagentResolver |
API Changes¶
TaskToolCallbackProvider removed¶
TaskToolCallbackProvider has been deleted. Replace it with TaskTool.builder() plus ClaudeSubagentType.builder().
Before:
var taskTools = TaskToolCallbackProvider.builder()
.subagentReferences(ClaudeSubagentReferences.fromResources(agentPaths))
.chatClientBuilder("default", chatClientBuilder.clone())
.skillsResources(skillPaths)
.braveApiKey(braveApiKey)
.build();
// Used as ToolCallbackProvider
chatClientBuilder.defaultToolCallbacks(taskTools);
After:
var taskTools = TaskTool.builder()
.subagentTypes(ClaudeSubagentType.builder()
.chatClientBuilder("default", chatClientBuilder.clone())
.skillsResources(skillPaths)
.braveApiKey(braveApiKey)
.build())
.build();
// Now returns a single ToolCallback (not a provider)
chatClientBuilder.defaultToolCallbacks(taskTools);
Key differences:
- Claude-specific config (chatClientBuilder, skillsResources, braveApiKey) moves into ClaudeSubagentType.builder()
- Built-in Claude subagent references are auto-registered when a Claude subagent type is present
- Custom subagent references are added via TaskTool.builder().subagentReferences(...)
- TaskTool.builder().build() returns a ToolCallback, not a ToolCallbackProvider
TaskTool.Builder simplified¶
The separate subagentResolvers() and subagentExecutors() methods are replaced by subagentTypes():
Before:
TaskTool.builder()
.subagentResolvers(new MyResolver())
.subagentExecutors(new MyExecutor())
.taskRepository(repo)
.build();
After:
Note: taskRepository now defaults to DefaultTaskRepository and no longer needs to be set explicitly.
TaskCall is now a top-level record¶
If you reference TaskTool.TaskCall directly, change to org.springaicommunity.agent.common.task.subagent.TaskCall.
A2A subagents with Claude subagents¶
When mixing local Claude and remote A2A subagents, register each type separately:
var taskTools = TaskTool.builder()
// Claude (local)
.subagentReferences(ClaudeSubagentReferences.fromResources(agentPaths))
.subagentTypes(ClaudeSubagentType.builder()
.chatClientBuilder("default", chatClientBuilder.clone())
.build())
// A2A (remote)
.subagentReferences(new SubagentReference("http://host:port/path", A2ASubagentDefinition.KIND))
.subagentTypes(new SubagentType(new A2ASubagentResolver(), new A2ASubagentExecutor()))
.build();