Skip to content

Commit cd71573

Browse files
committed
Fixes #3824 - Support latest Google Unified SDK to access Google AI Embedding Models - text embeddings
Signed-off-by: ddobrin <[email protected]>
1 parent 237e5d3 commit cd71573

File tree

13 files changed

+1424
-0
lines changed

13 files changed

+1424
-0
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Google Gen AI Embeddings module
2+
3+
Please note that at this time the *spring-ai-google-genai-embedding* module supports only text embeddings only.
4+
5+
This is due to the fact that the Google GenAI SDK supports text embeddings only, with multimedia embeddings pending.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
~ Copyright 2023-2024 the original author or authors.
4+
~
5+
~ Licensed under the Apache License, Version 2.0 (the "License");
6+
~ you may not use this file except in compliance with the License.
7+
~ You may obtain a copy of the License at
8+
~
9+
~ https://www.apache.org/licenses/LICENSE-2.0
10+
~
11+
~ Unless required by applicable law or agreed to in writing, software
12+
~ distributed under the License is distributed on an "AS IS" BASIS,
13+
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
~ See the License for the specific language governing permissions and
15+
~ limitations under the License.
16+
-->
17+
18+
<project xmlns="http://maven.apache.org/POM/4.0.0"
19+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
20+
<modelVersion>4.0.0</modelVersion>
21+
<parent>
22+
<groupId>org.springframework.ai</groupId>
23+
<artifactId>spring-ai-parent</artifactId>
24+
<version>1.1.0-SNAPSHOT</version>
25+
<relativePath>../../pom.xml</relativePath>
26+
</parent>
27+
<artifactId>spring-ai-google-genai-embedding</artifactId>
28+
<packaging>jar</packaging>
29+
<name>Spring AI Model - Google GenAI Embedding</name>
30+
<description>Google GenAI Gemini embedding models support</description>
31+
<url>https://github.com/spring-projects/spring-ai</url>
32+
33+
<scm>
34+
<url>https://github.com/spring-projects/spring-ai</url>
35+
<connection>git://github.com/spring-projects/spring-ai.git</connection>
36+
<developerConnection>[email protected]:spring-projects/spring-ai.git</developerConnection>
37+
</scm>
38+
39+
<properties>
40+
</properties>
41+
42+
<dependencies>
43+
44+
<dependency>
45+
<groupId>com.google.genai</groupId>
46+
<artifactId>google-genai</artifactId>
47+
<version>1.8.0</version>
48+
</dependency>
49+
50+
<!-- production dependencies -->
51+
<dependency>
52+
<groupId>org.springframework.ai</groupId>
53+
<artifactId>spring-ai-model</artifactId>
54+
<version>${project.parent.version}</version>
55+
</dependency>
56+
57+
<dependency>
58+
<groupId>org.springframework.ai</groupId>
59+
<artifactId>spring-ai-retry</artifactId>
60+
<version>${project.parent.version}</version>
61+
</dependency>
62+
63+
<!-- Spring Framework -->
64+
<dependency>
65+
<groupId>org.springframework</groupId>
66+
<artifactId>spring-context-support</artifactId>
67+
</dependency>
68+
69+
<dependency>
70+
<groupId>org.slf4j</groupId>
71+
<artifactId>slf4j-api</artifactId>
72+
</dependency>
73+
74+
<dependency>
75+
<groupId>io.micrometer</groupId>
76+
<artifactId>micrometer-observation-test</artifactId>
77+
<scope>test</scope>
78+
</dependency>
79+
80+
<!-- test dependencies -->
81+
<dependency>
82+
<groupId>org.springframework.ai</groupId>
83+
<artifactId>spring-ai-test</artifactId>
84+
<version>${project.version}</version>
85+
<scope>test</scope>
86+
</dependency>
87+
88+
</dependencies>
89+
90+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
/*
2+
* Copyright 2023-2024 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.ai.google.genai;
18+
19+
import com.google.genai.Client;
20+
21+
import org.springframework.util.Assert;
22+
import org.springframework.util.StringUtils;
23+
24+
/**
25+
* GoogleGenAiEmbeddingConnectionDetails represents the details of a connection to the
26+
* embedding service using the new Google Gen AI SDK. It provides methods to create and
27+
* configure the GenAI Client instance.
28+
*
29+
* @author Christian Tzolov
30+
* @author Mark Pollack
31+
* @author Ilayaperumal Gopinathan
32+
* @author Dan Dobrin
33+
* @since 1.0.0
34+
*/
35+
public class GoogleGenAiEmbeddingConnectionDetails {
36+
37+
public static final String DEFAULT_LOCATION = "us-central1";
38+
39+
public static final String DEFAULT_PUBLISHER = "google";
40+
41+
/**
42+
* Your project ID.
43+
*/
44+
private final String projectId;
45+
46+
/**
47+
* A location is a <a href="https://cloud.google.com/about/locations?hl=en">region</a>
48+
* you can specify in a request to control where data is stored at rest. For a list of
49+
* available regions, see <a href=
50+
* "https://cloud.google.com/vertex-ai/generative-ai/docs/learn/locations?hl=en">Generative
51+
* AI on Vertex AI locations</a>.
52+
*/
53+
private final String location;
54+
55+
/**
56+
* The API key for using Gemini Developer API. If null, Vertex AI mode will be used.
57+
*/
58+
private final String apiKey;
59+
60+
/**
61+
* The GenAI Client instance configured for this connection.
62+
*/
63+
private final Client genAiClient;
64+
65+
private GoogleGenAiEmbeddingConnectionDetails(String projectId, String location, String apiKey,
66+
Client genAiClient) {
67+
this.projectId = projectId;
68+
this.location = location;
69+
this.apiKey = apiKey;
70+
this.genAiClient = genAiClient;
71+
}
72+
73+
public static Builder builder() {
74+
return new Builder();
75+
}
76+
77+
public String getProjectId() {
78+
return this.projectId;
79+
}
80+
81+
public String getLocation() {
82+
return this.location;
83+
}
84+
85+
public String getApiKey() {
86+
return this.apiKey;
87+
}
88+
89+
public Client getGenAiClient() {
90+
return this.genAiClient;
91+
}
92+
93+
/**
94+
* Constructs the model endpoint name in the format expected by the embedding models.
95+
* @param modelName the model name (e.g., "text-embedding-004")
96+
* @return the full model endpoint name
97+
*/
98+
public String getModelEndpointName(String modelName) {
99+
// For the new SDK, we just return the model name as is
100+
// The SDK handles the full endpoint construction internally
101+
return modelName;
102+
}
103+
104+
public static class Builder {
105+
106+
/**
107+
* Your project ID.
108+
*/
109+
private String projectId;
110+
111+
/**
112+
* A location is a
113+
* <a href="https://cloud.google.com/about/locations?hl=en">region</a> you can
114+
* specify in a request to control where data is stored at rest. For a list of
115+
* available regions, see <a href=
116+
* "https://cloud.google.com/vertex-ai/generative-ai/docs/learn/locations?hl=en">Generative
117+
* AI on Vertex AI locations</a>.
118+
*/
119+
private String location;
120+
121+
/**
122+
* The API key for using Gemini Developer API. If null, Vertex AI mode will be
123+
* used.
124+
*/
125+
private String apiKey;
126+
127+
/**
128+
* Custom GenAI client instance. If provided, other settings will be ignored.
129+
*/
130+
private Client genAiClient;
131+
132+
public Builder projectId(String projectId) {
133+
this.projectId = projectId;
134+
return this;
135+
}
136+
137+
public Builder location(String location) {
138+
this.location = location;
139+
return this;
140+
}
141+
142+
public Builder apiKey(String apiKey) {
143+
this.apiKey = apiKey;
144+
return this;
145+
}
146+
147+
public Builder genAiClient(Client genAiClient) {
148+
this.genAiClient = genAiClient;
149+
return this;
150+
}
151+
152+
public GoogleGenAiEmbeddingConnectionDetails build() {
153+
// If a custom client is provided, use it directly
154+
if (this.genAiClient != null) {
155+
return new GoogleGenAiEmbeddingConnectionDetails(this.projectId, this.location, this.apiKey,
156+
this.genAiClient);
157+
}
158+
159+
// Otherwise, build a new client
160+
Client.Builder clientBuilder = Client.builder();
161+
162+
if (StringUtils.hasText(this.apiKey)) {
163+
// Use Gemini Developer API mode
164+
clientBuilder.apiKey(this.apiKey);
165+
}
166+
else {
167+
// Use Vertex AI mode
168+
Assert.hasText(this.projectId, "Project ID must be provided for Vertex AI mode");
169+
170+
if (!StringUtils.hasText(this.location)) {
171+
this.location = DEFAULT_LOCATION;
172+
}
173+
174+
clientBuilder.project(this.projectId).location(this.location).vertexAI(true);
175+
}
176+
177+
Client builtClient = clientBuilder.build();
178+
return new GoogleGenAiEmbeddingConnectionDetails(this.projectId, this.location, this.apiKey, builtClient);
179+
}
180+
181+
}
182+
183+
}

0 commit comments

Comments
 (0)