Skip to content

Commit 29b0b76

Browse files
committed
feat: added simple chat client
1 parent 5829ee8 commit 29b0b76

8 files changed

Lines changed: 202 additions & 0 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# Spring AI Simple Chat Client
2+
3+
A lightweight Spring Boot application demonstrating the integration of Spring AI with Amazon Bedrock to create a simple chat API.
4+
5+
## Features
6+
7+
- REST API endpoints for AI chat interactions
8+
- Support for both synchronous and streaming responses
9+
- Custom tool integration
10+
- Integration with Amazon Bedrock's Claude 3 Sonnet model
11+
12+
## Prerequisites
13+
14+
- Java 21
15+
- Maven
16+
- AWS account with access to Amazon Bedrock
17+
- AWS credentials configured locally
18+
19+
## Configuration
20+
21+
The application is configured to use Amazon Bedrock's Claude 3 Sonnet model in the EU West 1 region. You can modify these settings in `application.properties`:
22+
23+
```properties
24+
spring.application.name=agents
25+
spring.ai.bedrock.aws.region=eu-west-1
26+
spring.ai.bedrock.converse.chat.options.model=eu.anthropic.claude-3-7-sonnet-20250219-v1:0
27+
```
28+
29+
## Building and Running
30+
31+
```bash
32+
mvn spring-boot:run
33+
```
34+
35+
The application will start on port 8080 by default.
36+
37+
## API Endpoints
38+
39+
### 1. Synchronous Chat Endpoint
40+
41+
Send a prompt and receive a complete response:
42+
43+
```bash
44+
curl -XPOST 'http://localhost:8080/ai' \
45+
-H "Content-Type: application/json" \
46+
-d '{"prompt":"Tell me about Spring AI in 2 sentences."}'
47+
```
48+
49+
### 2. Streaming Chat Endpoint
50+
51+
Send a prompt and receive the response as a stream (useful for real-time UI updates):
52+
53+
```bash
54+
curl -XPOST -N 'http://localhost:8080/ai/stream' \
55+
-H "Content-Type: application/json" \
56+
-d '{"prompt":"Who is George Mallory?"}'
57+
```
58+
59+
### 3. With tool use
60+
61+
curl -XPOST -N 'http://localhost:8080/ai/stream' \
62+
-H "Content-Type: application/json" \
63+
-d '{"prompt":"What is the current date and time?"}'
64+
65+
## Project Structure
66+
67+
- `ChatController.java`: Defines the REST endpoints for chat interactions
68+
- `PromptRequest.java`: Simple record class for the request payload
69+
- `DateTimeTools.java`: Custom tool that provides date/time information to the AI
70+
- `AgentsApplication.java`: Spring Boot application entry point
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
4+
<modelVersion>4.0.0</modelVersion>
5+
<parent>
6+
<groupId>org.springframework.boot</groupId>
7+
<artifactId>spring-boot-starter-parent</artifactId>
8+
<version>3.4.5</version>
9+
<relativePath/> <!-- lookup parent from repository -->
10+
</parent>
11+
<groupId>com.unicorn</groupId>
12+
<artifactId>agents</artifactId>
13+
<version>0.0.1-SNAPSHOT</version>
14+
<name>agents</name>
15+
<description>Simple Bedrock Chat Client for Spring AI</description>
16+
<properties>
17+
<java.version>21</java.version>
18+
<spring-ai.version>1.0.0</spring-ai.version>
19+
</properties>
20+
<dependencies>
21+
<dependency>
22+
<groupId>org.springframework.ai</groupId>
23+
<artifactId>spring-ai-starter-model-bedrock-converse</artifactId>
24+
</dependency>
25+
<dependency>
26+
<groupId>org.springframework.boot</groupId>
27+
<artifactId>spring-boot-starter-web</artifactId>
28+
</dependency>
29+
<dependency>
30+
<groupId>org.springframework.boot</groupId>
31+
<artifactId>spring-boot-starter-test</artifactId>
32+
<scope>test</scope>
33+
</dependency>
34+
</dependencies>
35+
<dependencyManagement>
36+
<dependencies>
37+
<dependency>
38+
<groupId>org.springframework.ai</groupId>
39+
<artifactId>spring-ai-bom</artifactId>
40+
<version>${spring-ai.version}</version>
41+
<type>pom</type>
42+
<scope>import</scope>
43+
</dependency>
44+
</dependencies>
45+
46+
</dependencyManagement>
47+
48+
<build>
49+
<plugins>
50+
<plugin>
51+
<groupId>org.springframework.boot</groupId>
52+
<artifactId>spring-boot-maven-plugin</artifactId>
53+
</plugin>
54+
</plugins>
55+
</build>
56+
57+
</project>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.unicorn;
2+
3+
import org.springframework.boot.SpringApplication;
4+
import org.springframework.boot.autoconfigure.SpringBootApplication;
5+
6+
@SpringBootApplication
7+
public class AgentsApplication {
8+
9+
public static void main(String[] args) {
10+
SpringApplication.run(AgentsApplication.class, args);
11+
}
12+
13+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package com.unicorn.agents;
2+
3+
import org.springframework.ai.chat.client.ChatClient;
4+
import org.springframework.web.bind.annotation.*;
5+
import reactor.core.publisher.Flux;
6+
7+
@RestController
8+
public class ChatController {
9+
10+
private final ChatClient chatClient;
11+
12+
public ChatController (ChatClient.Builder chatClient){
13+
this.chatClient = chatClient
14+
.defaultTools(new DateTimeTools())
15+
.build();
16+
}
17+
18+
@PostMapping("/ai")
19+
public String myAgent(@RequestBody PromptRequest promptRequest){
20+
return chatClient.prompt().user(promptRequest.prompt()).call().chatResponse().toString();
21+
}
22+
23+
@PostMapping("/ai/stream")
24+
public Flux<String> myStreamingAgent(@RequestBody PromptRequest promptRequest){
25+
return chatClient.prompt().user(promptRequest.prompt()).stream().content();
26+
}
27+
28+
29+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.unicorn.agents;
2+
3+
import java.time.LocalDateTime;
4+
import org.springframework.ai.tool.annotation.Tool;
5+
import org.springframework.context.i18n.LocaleContextHolder;
6+
7+
class DateTimeTools {
8+
9+
@Tool(description = "Get the current date and time in the user's timezone")
10+
String getCurrentDateTime(String param) {
11+
return LocalDateTime.now().atZone(LocaleContextHolder.getTimeZone().toZoneId()).toString();
12+
}
13+
14+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package com.unicorn.agents;
2+
3+
public record PromptRequest(String prompt){};
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
spring.application.name=agents
2+
spring.ai.bedrock.aws.region=eu-west-1
3+
spring.ai.bedrock.converse.chat.options.model=eu.anthropic.claude-3-7-sonnet-20250219-v1:0
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.maschnetwork.agents;
2+
3+
import org.junit.jupiter.api.Test;
4+
import org.springframework.boot.test.context.SpringBootTest;
5+
6+
@SpringBootTest
7+
class AgentsApplicationTests {
8+
9+
@Test
10+
void contextLoads() {
11+
}
12+
13+
}

0 commit comments

Comments
 (0)