Contribution Guidelines
We welcome contributions to Spring AI Agents! This guide will help you get started with contributing to this community-maintained project.
1. Getting Started
1.1. Prerequisites
Before contributing, ensure you have:
-
Java 17 or higher
-
Maven 3.6.3 or higher
-
Git for version control
-
An IDE with Java support (IntelliJ IDEA, Eclipse, VS Code)
-
Agent CLI tools installed (Claude Code, Gemini CLI, etc.)
1.2. Development Environment Setup
-
Fork and Clone the Repository:
git clone https://github.com/yourusername/spring-ai-agents.git cd spring-ai-agents
-
Build the Project:
mvn clean install
-
Run Tests:
# Run unit and smoke tests (fast) mvn test # Run all tests including integration tests mvn test -Pfailsafe
-
Verify Agent CLIs:
# Verify Claude Code CLI claude --version # Verify Gemini CLI gemini --version
2. Types of Contributions
2.1. 1. Bug Fixes
Help us improve stability and reliability:
-
Bug Reports: Use GitHub Issues with detailed reproduction steps
-
Bug Fixes: Submit pull requests with tests demonstrating the fix
-
Regression Prevention: Add tests for edge cases and error conditions
2.2. 2. New Agent Integrations
Expand the ecosystem by adding new autonomous agents:
-
Agent Research: Evaluate new CLI agents for integration potential
-
SDK Development: Create Java SDKs following our established patterns
-
AgentModel Implementation: Build Spring AI integration adapters
-
Documentation: Provide comprehensive usage documentation
2.3. 3. Feature Enhancements
Improve existing functionality:
-
API Improvements: Enhance the AgentClient API based on user feedback
-
Performance Optimizations: Improve response times and resource usage
-
Configuration Options: Add new configuration capabilities
-
Error Handling: Improve error messages and recovery mechanisms
2.4. 4. Documentation
Help others use the library effectively:
-
API Documentation: Improve method and class documentation
-
Usage Examples: Add practical code examples and tutorials
-
Troubleshooting Guides: Document common issues and solutions
-
Architecture Documentation: Explain design decisions and patterns
3. Development Process
3.1. Code Standards
Follow these coding conventions:
3.1.1. Java Code Style
-
Formatting: Use Spring Java Format (automatically applied via Maven plugin)
-
Naming: Follow standard Java naming conventions
-
Documentation: Include Javadoc for all public APIs
-
Imports: Organize imports and avoid wildcard imports
// Good example
public class ClaudeCodeAgentModel implements AgentModel<AgentRequest, AgentResponse> {
private final ClaudeCodeClient client;
private final ClaudeCodeAgentOptions options;
/**
* Creates a new Claude Code agent model with the specified client and options.
*
* @param client the Claude Code client for CLI communication
* @param options configuration options for the agent
* @throws IllegalArgumentException if client or options are null
*/
public ClaudeCodeAgentModel(ClaudeCodeClient client, ClaudeCodeAgentOptions options) {
this.client = Objects.requireNonNull(client, "Client cannot be null");
this.options = Objects.requireNonNull(options, "Options cannot be null");
}
// Implementation...
}
3.1.2. Test Naming Conventions
Follow our standardized test naming:
-
Unit Tests: End with
Test
(e.g.,AgentClientTest
) -
Smoke Tests: Include
Smoke
in the name (e.g.,ClaudeQuerySmokeTest
) -
Integration Tests: End with
IT
(e.g.,ClaudeCodeClientIT
)
// Unit test example
class AgentClientTest {
@Test
void shouldCreateClientWithValidModel() {
// Test implementation
}
}
// Integration test example
class ClaudeCodeClientIT {
@Test
void shouldExecuteSimpleTaskSuccessfully() {
// Test implementation
}
}
3.2. Git Workflow
3.2.1. Branch Naming
Use descriptive branch names with prefixes:
-
feature/add-new-agent-support
-
bugfix/fix-timeout-handling
-
docs/improve-getting-started
-
test/add-integration-tests
3.2.2. Commit Messages
Write clear, descriptive commit messages:
# Good commit message
Add timeout configuration for Claude Code agent
- Add timeout option to ClaudeCodeAgentOptions
- Implement timeout handling in ClaudeCodeClient
- Add tests for timeout scenarios
- Update documentation with timeout examples
# Poor commit message
Fix bug
3.2.3. Pull Request Process
-
Create Feature Branch:
git checkout -b feature/my-new-feature
-
Make Changes: Implement your feature with tests and documentation
-
Run Tests: Ensure all tests pass
mvn clean test -Pfailsafe mvn spring-javaformat:apply
-
Commit Changes:
git add . git commit -m "Add new feature with comprehensive tests"
-
Push and Create PR:
git push origin feature/my-new-feature
-
Address Review Comments: Make requested changes and update PR
4. Testing Guidelines
4.1. Test Categories
Our test suite is organized into three categories:
4.1.1. Unit Tests (*Test.java
)
-
Purpose: Test individual components in isolation
-
Scope: Single class or method
-
Execution: Fast (< 1 second per test)
-
Dependencies: Use mocks for external dependencies
@ExtendWith(MockitoExtension.class)
class AgentClientTest {
@Mock
private AgentModel<AgentRequest, AgentResponse> mockModel;
@Test
void shouldCallModelWithCorrectRequest() {
// Given
AgentClient client = AgentClient.create(mockModel);
when(mockModel.call(any())).thenReturn(createMockResponse());
// When
AgentClientResponse response = client.run("test goal");
// Then
assertThat(response).isNotNull();
verify(mockModel).call(any(AgentRequest.class));
}
}
4.1.2. Smoke Tests (*SmokeTest.java
)
-
Purpose: Quick end-to-end validation
-
Scope: Critical paths with real agents
-
Execution: Fast (< 2 minutes total)
-
Dependencies: Real agent CLIs with minimal tasks
class ClaudeQuerySmokeTest {
@Test
@EnabledIf("org.springaicommunity.agents.claudecode.sdk.integration.ClaudeCliDiscovery#isClaudeCliAvailable")
void shouldExecuteSimpleQuery() {
// Test simple agent interaction
AgentClientResponse response = agentClient.run("Echo hello world");
assertThat(response.isSuccessful()).isTrue();
}
}
4.2. Writing Good Tests
4.2.1. Test Structure
Use the Given-When-Then pattern:
@Test
void shouldHandleTimeoutGracefully() {
// Given
ClaudeCodeAgentOptions options = ClaudeCodeAgentOptions.builder()
.timeout(Duration.ofMillis(100)) // Very short timeout
.build();
AgentClient client = createClientWithOptions(options);
// When
Exception exception = assertThrows(AgentTimeoutException.class, () -> {
client.run("Complex long-running goal");
});
// Then
assertThat(exception.getMessage()).contains("timed out");
assertThat(exception.getTimeout()).isEqualTo(Duration.ofMillis(100));
}
4.2.2. Test Data Management
Create reusable test utilities:
public class TestDataBuilder {
public static ClaudeCodeAgentOptions defaultOptions() {
return ClaudeCodeAgentOptions.builder()
.model("claude-sonnet-4-0")
.yolo(false)
.timeout(Duration.ofMinutes(2))
.build();
}
public static AgentRequest simpleRequest(String goal) {
return new AgentRequest(goal, Paths.get("."), Collections.emptyMap());
}
}
4.3. Cross-Platform Testing
Ensure compatibility across operating systems:
@Test
void shouldResolveCommandPathOnAllPlatforms() {
// Test path resolution on Windows, macOS, and Linux
String command = "claude";
String resolvedPath = ClaudeCliDiscovery.resolveCommandPath(command);
assertThat(resolvedPath).isNotNull();
assertThat(Paths.get(resolvedPath)).exists();
}
@EnabledOnOs({OS.WINDOWS})
@Test
void shouldHandleWindowsSpecificPaths() {
// Windows-specific test
}
@EnabledOnOs({OS.MAC, OS.LINUX})
@Test
void shouldHandleUnixSpecificPaths() {
// Unix-specific test
}
5. Adding New Agent Integrations
5.1. Research Phase
Before implementing a new agent integration:
-
Agent Evaluation:
-
Does it provide autonomous coding capabilities?
-
Is there a command-line interface available?
-
Does it support structured input/output?
-
Is it actively maintained?
-
-
Technical Assessment:
-
What programming languages does it support?
-
What are the installation requirements?
-
How does authentication work?
-
What are the rate limits and costs?
-
-
Community Need:
-
Is there demand for this integration?
-
How would it complement existing agents?
-
What unique capabilities does it provide?
-
5.2. Implementation Pattern
Follow this proven pattern for new agent integrations:
5.2.1. 1. Create SDK Module
provider-sdks/
└── your-agent-sdk/
├── pom.xml
└── src/
├── main/java/org/springaicommunity/agents/youragent/
│ ├── sdk/
│ │ ├── YourAgentClient.java
│ │ ├── YourAgentCommand.java
│ │ └── YourAgentResponse.java
│ └── exceptions/
└── test/java/
5.2.2. 2. Implement Core SDK Classes
public class YourAgentClient {
private final Path workingDirectory;
private final String commandPath;
public static YourAgentClient create() {
return create(Paths.get(System.getProperty("user.dir")));
}
public static YourAgentClient create(Path workingDirectory) {
String commandPath = YourAgentCliDiscovery.discoverYourAgentCommand();
return new YourAgentClient(workingDirectory, commandPath);
}
public YourAgentResponse execute(YourAgentCommand command) {
// Implementation follows established patterns
}
}
5.2.3. 3. Create AgentModel Integration
agent-models/
└── spring-ai-your-agent/
├── pom.xml
└── src/
└── main/java/org/springaicommunity/agents/youragent/
├── YourAgentModel.java
├── YourAgentOptions.java
└── YourAgentProperties.java
public class YourAgentModel implements AgentModel<AgentRequest, AgentResponse> {
private final YourAgentClient client;
private final YourAgentOptions options;
public YourAgentModel(YourAgentClient client, YourAgentOptions options) {
this.client = client;
this.options = options;
}
@Override
public AgentResponse call(AgentRequest request) {
// Convert AgentRequest to YourAgentCommand
// Execute via client
// Convert YourAgentResponse to AgentResponse
}
}
5.3. Integration Checklist
Before submitting a new agent integration:
-
SDK follows established patterns
-
All tests pass (unit, smoke, integration)
-
Cross-platform compatibility verified
-
Documentation is comprehensive
-
Error handling is robust
-
Configuration options are well-designed
-
Thread safety is ensured
-
Resource cleanup is proper
-
Examples are provided
-
Performance is acceptable
6. Documentation Standards
6.1. AsciiDoc Guidelines
Our documentation uses AsciiDoc format:
-
Structure: Use proper heading hierarchy
-
Code Examples: Include complete, runnable examples
-
Cross-References: Link related sections with
xref:
-
Formatting: Use appropriate text formatting (bold, italic, code)
= Your Agent SDK
:page-title: Your Agent SDK Documentation
:toc: left
:tabsize: 2
:sectnums:
The Your Agent SDK provides Java integration with YourAgent CLI.
== Overview
Brief description of the agent and its capabilities.
== Installation
=== Prerequisites
List requirements:
* YourAgent CLI installation
* API key configuration
* System requirements
=== Maven Dependencies
[source,xml]
<dependency> <groupId>org.springaicommunity.agents</groupId> <artifactId>spring-ai-your-agent</artifactId> <version>0.1.0-SNAPSHOT</version> </dependency>
== Basic Usage === Quick Start [source,java]
public class YourAgentExample { public static void main(String[] args) { // Step-by-step implementation } }
6.2. API Reference
Document all public APIs with:
-
Purpose: What does this API do?
-
Parameters: All parameters with types and descriptions
-
Return Values: What does it return?
-
Exceptions: What exceptions might be thrown?
-
Examples: Show typical usage
6.3. Code Examples
Provide complete, runnable examples:
// Bad: Incomplete example
YourAgentClient client = YourAgentClient.create();
client.execute(command);
// Good: Complete example
import org.springaicommunity.agents.youragent.YourAgentClient;
import org.springaicommunity.agents.youragent.YourAgentCommand;
public class YourAgentExample {
public static void main(String[] args) {
// 1. Create client with working directory
YourAgentClient client = YourAgentClient.create(
Paths.get("/path/to/project")
);
// 2. Create command
YourAgentCommand command = YourAgentCommand.builder()
.goal("Create a simple REST controller")
.build();
// 3. Execute command
YourAgentResponse response = client.execute(command);
// 4. Handle response
if (response.isSuccessful()) {
System.out.println("Result: " + response.getResult());
} else {
System.err.println("Failed: " + response.getError());
}
}
}
7. Community Support
7.1. Getting Help
-
GitHub Discussions: Ask questions and share ideas
-
GitHub Issues: Report bugs and request features
-
Stack Overflow: Tag questions with
spring-ai-agents
-
Documentation: Check our comprehensive guides
7.2. Reporting Issues
When reporting bugs, include:
-
Version: Which version are you using?
-
Environment: OS, Java version, agent CLI versions
-
Steps to Reproduce: Detailed reproduction steps
-
Expected Behavior: What should happen?
-
Actual Behavior: What actually happens?
-
Code Sample: Minimal example demonstrating the issue
8. Release Process
9. Code of Conduct
We are committed to providing a welcoming and inclusive environment:
-
Be Respectful: Treat all community members with respect
-
Be Collaborative: Help others learn and contribute
-
Be Patient: Remember that everyone has different experience levels
-
Be Constructive: Provide helpful feedback and suggestions
10. Licensing
This project is licensed under the Apache License 2.0. By contributing, you agree to license your contributions under the same terms.
11. Next Steps
Ready to contribute? Here’s how to get started:
-
Read the Code: Familiarize yourself with the existing codebase
-
Start Small: Begin with documentation improvements or small bug fixes
-
Ask Questions: Don’t hesitate to ask for help in GitHub Discussions
-
Follow Patterns: Study existing implementations before creating new ones
-
Test Thoroughly: Ensure your contributions are well-tested
-
Document Well: Help others understand your contributions
Thank you for contributing to Spring AI Agents! 🚀