Skip to content

Commit 78fc9a4

Browse files
committed
code update
1 parent 88df28a commit 78fc9a4

File tree

10 files changed

+60
-55
lines changed

10 files changed

+60
-55
lines changed

LICENSE

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -175,18 +175,7 @@
175175

176176
END OF TERMS AND CONDITIONS
177177

178-
APPENDIX: How to apply the Apache License to your work.
179-
180-
To apply the Apache License to your work, attach the following
181-
boilerplate notice, with the fields enclosed by brackets "[]"
182-
replaced with your own identifying information. (Don't include
183-
the brackets!) The text should be enclosed in the appropriate
184-
comment syntax for the file format. We also recommend that a
185-
file or class name and description of purpose be included on the
186-
same "printed page" as the copyright notice for easier
187-
identification within third-party archives.
188-
189-
Copyright [yyyy] [name of copyright owner]
178+
Copyright 2025 Fu Cheng
190179

191180
Licensed under the Apache License, Version 2.0 (the "License");
192181
you may not use this file except in compliance with the License.

README.md

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,20 +10,24 @@ How to run:
1010

1111
1. Requires Java 21 to build and run.
1212
2. Start Postgres database using Docker Compose.
13-
3. Start the server and use [Swagger UI](http://localhost:8080/swagger-ui/index.html) to run query.
13+
3. Start the server and use [Chat Agent UI](http://localhost:8080/webjars/chat-agent-ui/index.html) to run query.
1414

1515
Sample query:
1616

1717
```text
18-
how many movies are produced in the United States?
18+
How many movies were produced in the United States?
1919
```
2020

2121
Output:
2222

2323
```text
24-
There are 2,058 movies produced in the United States.
24+
The total number of movies produced in the United States is 2058.
2525
```
2626

27+
See the screenshot below.
28+
29+
![Chat Agent UI](simple-text-to-sql-ui.png)
30+
2731
## Full Text-to-SQL Implementation
2832

2933
For a complete Text-to-SQL implementation, check out my [course](https://www.udemy.com/course/spring-ai-text-to-sql/?referralCode=6180D9A02FA8BA9D4F60).

pom.xml

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
<parent>
77
<groupId>org.springframework.boot</groupId>
88
<artifactId>spring-boot-starter-parent</artifactId>
9-
<version>3.3.4</version>
9+
<version>3.4.4</version>
1010
<relativePath/>
1111
</parent>
1212

@@ -18,7 +18,9 @@
1818
<properties>
1919
<java.version>21</java.version>
2020
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
21-
<spring-ai.version>1.0.0-M5</spring-ai.version>
21+
<spring-ai.version>1.0.0-M6</spring-ai.version>
22+
<chat-agent-ui.version>0.11.0</chat-agent-ui.version>
23+
<llm-agent-spec.version>0.1.2</llm-agent-spec.version>
2224
</properties>
2325

2426
<dependencyManagement>
@@ -68,6 +70,16 @@
6870
<artifactId>commons-csv</artifactId>
6971
<version>1.12.0</version>
7072
</dependency>
73+
<dependency>
74+
<groupId>com.javaaidev.chatagentui</groupId>
75+
<artifactId>chat-agent-ui</artifactId>
76+
<version>${chat-agent-ui.version}</version>
77+
</dependency>
78+
<dependency>
79+
<groupId>com.javaaidev.llmagentspec</groupId>
80+
<artifactId>spring-ai-adapter</artifactId>
81+
<version>${llm-agent-spec.version}</version>
82+
</dependency>
7183
<dependency>
7284
<groupId>org.junit.jupiter</groupId>
7385
<artifactId>junit-jupiter-api</artifactId>
@@ -98,15 +110,5 @@
98110
<enabled>false</enabled>
99111
</snapshots>
100112
</repository>
101-
<repository>
102-
<id>spring-snapshots</id>
103-
<name>Spring Snapshots</name>
104-
<url>https://repo.spring.io/snapshot</url>
105-
<releases>
106-
<enabled>false</enabled>
107-
</releases>
108-
</repository>
109113
</repositories>
110-
111-
112114
</project>

simple-text-to-sql-ui.png

56.2 KB
Loading

src/main/java/com/javaaidev/text2sql/DatabaseMetadataAdvisor.java

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@
77
import org.slf4j.LoggerFactory;
88
import org.springframework.ai.chat.client.advisor.api.AdvisedRequest;
99
import org.springframework.ai.chat.client.advisor.api.AdvisedResponse;
10+
import org.springframework.ai.chat.client.advisor.api.BaseAdvisor;
1011
import org.springframework.ai.chat.client.advisor.api.CallAroundAdvisor;
1112
import org.springframework.ai.chat.client.advisor.api.CallAroundAdvisorChain;
1213
import org.springframework.core.Ordered;
1314

1415
/**
1516
* Advisor to update system text of the prompt
1617
*/
17-
public class DatabaseMetadataAdvisor implements CallAroundAdvisor {
18+
public class DatabaseMetadataAdvisor implements BaseAdvisor {
1819

1920
private static final String DEFAULT_SYSTEM_TEXT = """
2021
You are a Postgres expert. Please help to generate a Postgres query, then run the query to answer the question. The output should be in tabular format.
@@ -45,15 +46,18 @@ private String getDatabaseMetadata() {
4546
}
4647

4748
@Override
48-
public AdvisedResponse aroundCall(AdvisedRequest advisedRequest,
49-
CallAroundAdvisorChain chain) {
49+
public AdvisedRequest before(AdvisedRequest advisedRequest) {
5050
var systemParams = new HashMap<>(advisedRequest.systemParams());
5151
systemParams.put("table_schemas", tableSchemas);
52-
var request = AdvisedRequest.from(advisedRequest)
52+
return AdvisedRequest.from(advisedRequest)
5353
.systemText(DEFAULT_SYSTEM_TEXT)
5454
.systemParams(systemParams)
5555
.build();
56-
return chain.nextAroundCall(request);
56+
}
57+
58+
@Override
59+
public AdvisedResponse after(AdvisedResponse advisedResponse) {
60+
return advisedResponse;
5761
}
5862

5963
@Override
Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
package com.javaaidev.text2sql.controller;
22

3+
import com.javaaidev.chatagent.model.ChatAgentRequest;
4+
import com.javaaidev.chatagent.model.ChatAgentResponse;
5+
import com.javaaidev.chatagent.springai.ModelAdapter;
36
import com.javaaidev.text2sql.DatabaseMetadataAdvisor;
47
import org.springframework.ai.chat.client.ChatClient;
5-
import org.springframework.ai.openai.OpenAiChatOptions;
6-
import org.springframework.ai.openai.api.OpenAiApi.ChatModel;
8+
import org.springframework.ai.chat.messages.Message;
9+
import org.springframework.http.codec.ServerSentEvent;
710
import org.springframework.web.bind.annotation.PostMapping;
811
import org.springframework.web.bind.annotation.RequestBody;
912
import org.springframework.web.bind.annotation.RestController;
13+
import reactor.core.publisher.Flux;
1014

1115
@RestController
1216
public class ChatController {
@@ -19,14 +23,12 @@ public ChatController(ChatClient.Builder builder,
1923
}
2024

2125
@PostMapping("/chat")
22-
public ChatResponse chat(@RequestBody ChatRequest request) {
23-
return new ChatResponse(
24-
chatClient.prompt().user(request.input())
25-
.options(OpenAiChatOptions.builder()
26-
.model(ChatModel.GPT_4_O_MINI)
27-
.temperature(0.0)
28-
.function("runSqlQuery")
29-
.build())
30-
.call().content());
26+
public Flux<ServerSentEvent<ChatAgentResponse>> chat(@RequestBody ChatAgentRequest request) {
27+
return ModelAdapter.toStreamingResponse(
28+
chatClient.prompt()
29+
.messages(ModelAdapter.fromRequest(request).toArray(new Message[0]))
30+
.tools("runSqlQuery")
31+
.stream()
32+
.chatResponse());
3133
}
3234
}
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package com.javaaidev.text2sql.metadata;
22

3-
public record ColumnInfo(String name, String dataType, String description) {
3+
public record ColumnInfo(
4+
String name,
5+
String dataType,
6+
String description) {
47

58
}

src/main/java/com/javaaidev/text2sql/metadata/TableInfo.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

33
import java.util.List;
44

5-
public record TableInfo(String name, String description, String catalog,
6-
String schema, List<ColumnInfo> columns) {
5+
public record TableInfo(
6+
String name,
7+
String description,
8+
String catalog,
9+
String schema,
10+
List<ColumnInfo> columns) {
711

812
}

src/main/java/com/javaaidev/text2sql/tool/RunSqlQueryTool.java

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@
22

33
import java.io.IOException;
44
import java.util.Map;
5-
import java.util.Objects;
65
import java.util.function.Function;
7-
import java.util.stream.Collectors;
86
import org.apache.commons.csv.CSVFormat;
9-
import org.apache.commons.csv.CSVPrinter;
107
import org.slf4j.Logger;
118
import org.slf4j.LoggerFactory;
129
import org.springframework.jdbc.core.simple.JdbcClient;
@@ -37,7 +34,7 @@ public RunSqlQueryResponse apply(RunSqlQueryRequest request) {
3734
}
3835
}
3936

40-
private String runQuery(String query) {
37+
private String runQuery(String query) throws IOException {
4138
var rows = jdbcClient.sql(query)
4239
.query().listOfRows();
4340
if (CollectionUtils.isEmpty(rows)) {
@@ -51,11 +48,7 @@ private String runQuery(String query) {
5148
.build();
5249
var builder = new StringBuilder();
5350
for (Map<String, Object> row : rows) {
54-
try {
55-
printer.printRecord(builder, fields.stream().map(row::get).toArray());
56-
} catch (IOException e) {
57-
throw new RuntimeException(e);
58-
}
51+
printer.printRecord(builder, fields.stream().map(row::get).toArray());
5952
}
6053
return builder.toString();
6154
}

src/main/resources/application.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ spring:
77
ai:
88
openai:
99
api-key: ${OPENAI_API_KEY:demo}
10+
chat:
11+
options:
12+
model: gpt-4o-mini
13+
temperature: 0.0
1014
datasource:
1115
url: jdbc:postgresql://localhost:5432/postgres
1216
username: postgres

0 commit comments

Comments
 (0)