Spring AI is released under the Apache 2.0 license. If you would like to contribute something, or want to hack on the code, this document should help you get started.
This project adheres to the Contributor Covenant code of conduct. By participating, you are expected to uphold this code. Please report unacceptable behavior to code-of-conduct@spring.io.
We accept contributions created with the help of AI coding agents, but they must be carefully reviewed by a human who remains accountable for the quality of the contribution. Contributions submitted by GitHub accounts controlled by autonomous AI bots are forbidden and will result in permanent bans.
If you think you have found a security vulnerability in Spring AI please DO NOT disclose it publicly until we've had a chance to fix it. Please don't report security vulnerabilities using GitHub issues or pull requests, instead head over to https://spring.io/security-policy and learn how to disclose them responsibly.
If you have a question, check Stack Overflow using this list of tags or Spring AI discussions. Find an existing discussion, or start a new one if necessary.
Is there already an existing issue or a pull request that addresses your concern? Search to see if you can find something similar before creating a new one.
If you are reporting a bug, please help to speed up problem diagnosis by providing as much information as possible. Ideally, that would include a small sample project that reproduces the problem, shared with a link to a related source repository or attached as an archive with instructions on how to reproduce.
You can also submit an enhancement or a new feature proposal.
The issue title is used to generate the changelog so please use a short and descriptive text with types or filenames enclosed in backticks.
Should you create an issue first? No, just create the pull request and use the description to provide context and motivation, as you would for an issue. You only have to create an issue if you want to start a discussion first.
Please don't submit pull requests:
- With GitHub accounts managed by autonomous AI bots
- For already assigned issues (as the assignee is or plans to work on it)
- For straightforward or polish-style changes
The pull request title is used to generate the changelog so please use a short and descriptive text with types or filenames enclosed in backticks. If your pull request is related to an issue, please mention the related issue with its number in the PR description (not in the title), for example "Fixes #123".
Before submitting a pull request:
- Add new tests that exercise the code you have added or modified
- Run the build and tests locally with
./mvnw clean package - If possible run integration tests related to the part you modify (see related documentation below)
- Any code needs to be carefully reviewed by a human, especially when generated by a coding agent
A commit message should include a short title (if possible less than 50 characters) starting with an uppercase verb.
The title should not include prefixes like fix:, feat: or docs: or the issue/PR number.
- ✅ Add Contribution Guidelines
- ❌ GH-123: Add Contribution Guidelines
- ❌ docs: Add Contribution Guidelines
- ❌ Add Contribution Guidelines (#123)
The commit description should be wrapped at approximately 72 characters.
Commit messages should allow discoverability of related issues and PRs by linking them after the description with for example Closes #123 if the issue number is 123.
That allows bi-directional navigation from the commit to the issue/PR, but also in the other way around as related mentions are added by GitHub.
All commits must include a Signed-off-by trailer at the end of each commit message to indicate that the contributor agrees to the Developer Certificate of Origin. For additional details, please refer to the blog post Hello DCO, Goodbye CLA: Simplifying Contributions to Spring.
Please find below the example of a typical commit message:
Add Contribution Guidelines
This commit adds CONTRIBUTING.md describing the Contribution
procedure, mentions Contribution Guidelines in the README.md and
mentions CODE_OF_CONDUCT in the README.md.
Fixes #123
Signed-off-by: Firstname Lastname <username@users.noreply.github.com>
If you want to only reference some issue or PR without closing it, you can use See #123.
Annotations should be enclosed in backticks to avoid mentioning potential related GitHub users.
If the commit has both an issue and a PR associated, the Spring AI committer merging the PR should reference both the issue and the PR and ensure the title does not contain the number of the PR, for example with an issue #123 and a PR #456:
Add Contribution Guidelines
...
Fixes #123
Closes #456
Signed-off-by: Firstname Lastname <username@users.noreply.github.com>
Spring AI source code style follows the checkstyle guidelines used by the core Spring Framework project with some exceptions. See also related IntelliJ IDEA Editor Settings.
The code is formatted using the java-format plugin as part of the build. Correct formatting is enforced by CI.
To format the code specifically:
./mvnw process-sourcesNote that this will not format the import order which is documented below.
Please carefully follow the whitespace and formatting conventions already present in the framework.
- UTF-8 encoding
- Tabs, not spaces
- Unix (LF), not DOS (CRLF) line endings
- Eliminate all trailing whitespace
- Wrap Javadoc at 90 characters
- Aim to wrap code at 120 characters, but favor readability over wrapping
- Preserve existing formatting; i.e. do not reformat code for its own sake
- For plain text documents like
.adocor.md, one sentence per line
The import statements are structured as follows:
- import
java.* - blank line
- import
javax.* - import
jakarta.* - blank line
- import all other imports
- blank line
- import
org.springframework.* - blank line
- import static all other imports
Static imports should not be used in production code, but they should be used in test code, especially for things like import static org.assertj.core.api.Assertions.assertThat;.
Although static imports are generally forbidden in production code, the following are use cases for which static imports are permissible.
- constants (including enum constants): such as those in
java.nio.charset.StandardCharsetsororg.springframework.core.annotation.MergedAnnotations.SearchStrategy - static factory methods for third-party DSLs: such as the methods in
org.junit.platform.engine.discovery.DiscoverySelectorswhen used with the JUnit PlatformLauncherAPI
Wildcard imports such as import java.util.* or import static org.assertj.core.api.Assertions.* are forbidden, even in test code.
A source file consists of the following, in this exact order:
- License
- Package statement
- Import statements
- Exactly one top-level class
Exactly one blank line separates each of the above sections.
/*
* Copyright 2023-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/Use @since tags for newly-added public API types and methods e.g.
/**
* ...
*
* @since 2.0.0
*/The project can be built from the root directory using the standard Maven command:
./mvnw clean packageThe project targets and builds artifacts compatible with Java 17+, and requires a JDK with support for the -XDaddTypeAnnotationsToSymbol javac argument, like Liberica 17.0.19+, for nullability checks.
The recommended JDK is specified in the .sdkmanrc file, which can be installed and configured with the SDKMAN! tool:
sdk env installto install the related JDK locallysdk envto use the related JDK
NOTE: Make sure to use a JDK with the same architecture as your processor, not an emulated one (for example with Rosetta on Mac) as Spring AI requires components that depend on your specific CPU architecture (PyTorch for example). If you are unsure if you have the correct JDK distribution for your CPU, run the command java -XshowSettings:properties -version 2>&1 | grep os.arch to validate that it matches your machine.
The Maven build-cache extension is enabled by default to speedup builds.
If you suspect the build cache is in an invalid state (build broken for no identified reason), try to run the build while disabling the build cache, for example with:
./mvnw -Dmaven.build.cache.enabled=false clean packageIf the build passes without the cache, please file an issue describing with as much detail as possible how that happened, and remove the local cache as a workaround:
rm -rf ~/.m2/build-cache/There are many integration tests, so it often isn't realistic to run them all at once. Note that you should set API key environment variables for model providers before running. If the API key isn't set for a specific model provider, the integration test is skipped.
To run the integration test for a specific module:
./mvnw -am -pl spring-ai-spring-boot-testcontainers -Pintegration-tests verifyTo run a specific integration test allowing for up to two attempts to succeed (this is useful when a hosted service is not reliable or times out):
./mvnw -am -pl vector-stores/spring-ai-pgvector-store -Pintegration-tests -Dfailsafe.failIfNoSpecifiedTests=false -Dfailsafe.rerunFailingTestsCount=2 -Dit.test=PgVectorStoreIT verifyA quick pass through the most important pathways that runs integration tests can be done with the profile -Pci-fast-integration-tests and is used in the main CI build of this project.
Full integration tests are done regularly in the Spring AI Integration Tests repository.
To check javadocs using the javadoc:javadoc:
./mvnw javadoc:javadocTo build the docs:
./mvnw -pl spring-ai-docs antoraThe generated documentation is available at spring-ai-docs/target/antora/site/index.html.