Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-parent</artifactId>
<version>2.0.0-SNAPSHOT</version>
<relativePath>../../../../../../pom.xml</relativePath>
</parent>
<artifactId>spring-ai-autoconfigure-model-chat-memory-repository-s3</artifactId>
<packaging>jar</packaging>
<name>Spring AI S3 Chat Memory Repository Auto Configuration</name>
<description>Spring S3 AI Chat Memory Repository Auto Configuration</description>
<url>https://github.com/spring-projects/spring-ai</url>

<scm>
<url>https://github.com/spring-projects/spring-ai</url>
<connection>git://github.com/spring-projects/spring-ai.git</connection>
<developerConnection>[email protected]:spring-projects/spring-ai.git</developerConnection>
</scm>

<dependencies>

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-model-chat-memory-repository-s3</artifactId>
<version>${project.parent.version}</version>
</dependency>

<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-autoconfigure-model-chat-memory</artifactId>
<version>${project.parent.version}</version>
</dependency>

<!-- Boot dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>

<!-- Test dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-junit-jupiter</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers-localstack</artifactId>
<scope>test</scope>
</dependency>

</dependencies>

</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/*
* Copyright 2023-2025 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.
*/

package org.springframework.ai.autoconfigure.chat.memory.repository.s3;

import java.net.URI;

import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
import software.amazon.awssdk.services.s3.S3ClientBuilder;
import software.amazon.awssdk.services.s3.model.StorageClass;

import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.memory.ChatMemoryRepository;
import org.springframework.ai.chat.memory.repository.s3.S3ChatMemoryRepository;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.util.StringUtils;

/**
* Auto-configuration for S3 chat memory repository.
*
* @author Yuriy Bezsonov
* @since 2.0.0
*/
@AutoConfiguration
@ConditionalOnClass({ S3Client.class, ChatMemoryRepository.class })
@EnableConfigurationProperties(S3ChatMemoryProperties.class)
@ConditionalOnProperty(prefix = "spring.ai.chat.memory.repository.s3", name = "bucket-name")
public class S3ChatMemoryAutoConfiguration {

/**
* Creates an S3Client bean if one is not already present.
* @param properties the S3 chat memory properties
* @return configured S3Client
*/
@Bean
@ConditionalOnMissingBean
public S3Client s3Client(final S3ChatMemoryProperties properties) {
S3ClientBuilder builder = S3Client.builder();

// Set region
if (StringUtils.hasText(properties.getRegion())) {
builder.region(Region.of(properties.getRegion()));
}

// Support for custom endpoint (useful for S3-compatible services
// like MinIO)
String endpoint = System.getProperty("spring.ai.chat.memory.repository.s3.endpoint");
if (StringUtils.hasText(endpoint)) {
builder.endpointOverride(URI.create(endpoint));
}

return builder.build();
}

/**
* Creates an S3ChatMemoryRepository bean if one is not already present.
* @param s3Client the S3 client
* @param properties the S3 chat memory properties
* @return configured S3ChatMemoryRepository
*/
@Bean
@ConditionalOnMissingBean({ S3ChatMemoryRepository.class, ChatMemory.class, ChatMemoryRepository.class })
public S3ChatMemoryRepository s3ChatMemoryRepository(final S3Client s3Client,
final S3ChatMemoryProperties properties) {
StorageClass storageClass = StorageClass.fromValue(properties.getStorageClass());

return S3ChatMemoryRepository.builder()
.s3Client(s3Client)
.bucketName(properties.getBucketName())
.keyPrefix(properties.getKeyPrefix())
.initializeBucket(properties.isInitializeBucket())
.storageClass(storageClass)
.build();
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright 2023-2025 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.
*/

package org.springframework.ai.autoconfigure.chat.memory.repository.s3;

import org.springframework.boot.context.properties.ConfigurationProperties;

/**
* Configuration properties for S3 chat memory repository.
*
* @author Yuriy Bezsonov
* @since 2.0.0
*/
@ConfigurationProperties(prefix = "spring.ai.chat.memory.repository.s3")
public class S3ChatMemoryProperties {

/**
* The name of the S3 bucket where conversation data will be stored.
*/
private String bucketName;

/**
* The prefix to use for S3 object keys. Defaults to "chat-memory".
*/
private String keyPrefix = "chat-memory";

/**
* The AWS region to use for S3 operations. Defaults to "us-east-1".
*/
private String region = "us-east-1";

/**
* Whether to automatically create the S3 bucket if it doesn't exist. Defaults to
* false.
*/
private boolean initializeBucket = false;

/**
* S3 storage class for conversation objects. Defaults to "STANDARD". Supported
* values: STANDARD, STANDARD_IA, ONEZONE_IA, REDUCED_REDUNDANCY.
*/
private String storageClass = "STANDARD";

/**
* Gets the S3 bucket name.
* @return the bucket name
*/
public String getBucketName() {
return this.bucketName;
}

/**
* Sets the S3 bucket name.
* @param name the bucket name to set
*/
public void setBucketName(final String name) {
this.bucketName = name;
}

/**
* Gets the S3 key prefix.
* @return the key prefix
*/
public String getKeyPrefix() {
return this.keyPrefix;
}

/**
* Sets the S3 key prefix.
* @param prefix the key prefix to set
*/
public void setKeyPrefix(final String prefix) {
this.keyPrefix = prefix;
}

/**
* Gets the AWS region.
* @return the region
*/
public String getRegion() {
return this.region;
}

/**
* Sets the AWS region.
* @param awsRegion the region to set
*/
public void setRegion(final String awsRegion) {
this.region = awsRegion;
}

/**
* Gets whether to initialize bucket.
* @return true if bucket should be initialized
*/
public boolean isInitializeBucket() {
return this.initializeBucket;
}

/**
* Sets whether to initialize bucket.
* @param initialize true to initialize bucket
*/
public void setInitializeBucket(final boolean initialize) {
this.initializeBucket = initialize;
}

/**
* Gets the storage class.
* @return the storage class
*/
public String getStorageClass() {
return this.storageClass;
}

/**
* Sets the storage class.
* @param storage the storage class to set
*/
public void setStorageClass(final String storage) {
this.storageClass = storage;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright 2023-2025 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.
*/

/**
* Auto-configuration for S3-based Spring AI chat memory repository.
*
* <p>
* This package provides Spring Boot auto-configuration classes for automatically
* configuring S3 chat memory repository when the appropriate dependencies are present on
* the classpath.
*
* @author Yuriy Bezsonov
* @since 2.0.0
*/
package org.springframework.ai.autoconfigure.chat.memory.repository.s3;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.springframework.ai.autoconfigure.chat.memory.repository.s3.S3ChatMemoryAutoConfiguration
Loading