Skip to content

Commit f924109

Browse files
committed
added proxy support for Vertex and Vertex Gemini.
1 parent bbacbfe commit f924109

File tree

10 files changed

+162
-6
lines changed

10 files changed

+162
-6
lines changed

model-providers/google/vertex-ai-gemini/runtime/src/main/java/io/quarkiverse/langchain4j/vertexai/runtime/gemini/VertexAiGeminiChatLanguageModel.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.quarkiverse.langchain4j.vertexai.runtime.gemini;
22

3+
import java.net.InetSocketAddress;
4+
import java.net.Proxy;
35
import java.net.URI;
46
import java.net.URISyntaxException;
57
import java.time.Duration;
@@ -42,12 +44,24 @@ private VertexAiGeminiChatLanguageModel(Builder builder) {
4244
.connectTimeout(builder.timeout.toSeconds(), TimeUnit.SECONDS)
4345
.readTimeout(builder.timeout.toSeconds(), TimeUnit.SECONDS);
4446

47+
if (builder.proxy != null) {
48+
if (builder.proxy.type() != Proxy.Type.HTTP) {
49+
throw new IllegalArgumentException("Only HTTP type proxy is supported");
50+
}
51+
if (!(builder.proxy.address() instanceof InetSocketAddress)) {
52+
throw new IllegalArgumentException("Unsupported proxy type");
53+
}
54+
InetSocketAddress socketAddress = (InetSocketAddress) builder.proxy.address();
55+
restApiBuilder.proxyAddress(socketAddress.getHostName(), socketAddress.getPort());
56+
}
57+
4558
if (builder.logRequests || builder.logResponses) {
4659
restApiBuilder.loggingScope(LoggingScope.REQUEST_RESPONSE);
4760
restApiBuilder.clientLogger(new VertxAiGeminiRestApi.VertxAiClientLogger(builder.logRequests,
4861
builder.logResponses));
4962
}
5063
restApiBuilder.register(new ModelAuthProviderFilter(builder.modelId));
64+
5165
restApi = restApiBuilder.build(VertxAiGeminiRestApi.class);
5266
} catch (URISyntaxException e) {
5367
throw new RuntimeException(e);
@@ -79,6 +93,7 @@ public static final class Builder {
7993
private Boolean logRequests = false;
8094
private Boolean logResponses = false;
8195
private List<ChatModelListener> listeners = Collections.emptyList();
96+
private Proxy proxy;
8297

8398
public Builder baseUrl(Optional<String> baseUrl) {
8499
this.baseUrl = baseUrl;
@@ -150,6 +165,11 @@ public Builder listeners(List<ChatModelListener> listeners) {
150165
return this;
151166
}
152167

168+
public Builder proxy(Proxy proxy) {
169+
this.proxy = proxy;
170+
return this;
171+
}
172+
153173
public VertexAiGeminiChatLanguageModel build() {
154174
return new VertexAiGeminiChatLanguageModel(this);
155175
}

model-providers/google/vertex-ai-gemini/runtime/src/main/java/io/quarkiverse/langchain4j/vertexai/runtime/gemini/VertexAiGeminiEmbeddingModel.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.quarkiverse.langchain4j.vertexai.runtime.gemini;
22

3+
import java.net.InetSocketAddress;
4+
import java.net.Proxy;
35
import java.net.URI;
46
import java.net.URISyntaxException;
57
import java.time.Duration;
@@ -39,6 +41,17 @@ public VertexAiGeminiEmbeddingModel(Builder builder) {
3941
.connectTimeout(builder.timeout.toSeconds(), TimeUnit.SECONDS)
4042
.readTimeout(builder.timeout.toSeconds(), TimeUnit.SECONDS);
4143

44+
if (builder.proxy != null) {
45+
if (builder.proxy.type() != Proxy.Type.HTTP) {
46+
throw new IllegalArgumentException("Only HTTP type proxy is supported");
47+
}
48+
if (!(builder.proxy.address() instanceof InetSocketAddress)) {
49+
throw new IllegalArgumentException("Unsupported proxy type");
50+
}
51+
InetSocketAddress socketAddress = (InetSocketAddress) builder.proxy.address();
52+
restApiBuilder.proxyAddress(socketAddress.getHostName(), socketAddress.getPort());
53+
}
54+
4255
if (builder.logRequests || builder.logResponses) {
4356
restApiBuilder.loggingScope(LoggingScope.REQUEST_RESPONSE);
4457
restApiBuilder.clientLogger(new VertxAiGeminiRestApi.VertxAiClientLogger(builder.logRequests,
@@ -77,6 +90,7 @@ public static final class Builder {
7790
private Duration timeout = Duration.ofSeconds(10);
7891
private Boolean logRequests = false;
7992
private Boolean logResponses = false;
93+
private Proxy proxy;
8094

8195
public Builder baseUrl(Optional<String> baseUrl) {
8296
this.baseUrl = baseUrl;
@@ -128,6 +142,11 @@ public Builder logResponses(boolean logResponses) {
128142
return this;
129143
}
130144

145+
public Builder proxy(Proxy proxy) {
146+
this.proxy = proxy;
147+
return this;
148+
}
149+
131150
public VertexAiGeminiEmbeddingModel build() {
132151
return new VertexAiGeminiEmbeddingModel(this);
133152
}

model-providers/google/vertex-ai-gemini/runtime/src/main/java/io/quarkiverse/langchain4j/vertexai/runtime/gemini/VertexAiGeminiRecorder.java

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import static io.quarkiverse.langchain4j.runtime.OptionalUtil.firstOrDefault;
44

5+
import java.net.InetSocketAddress;
6+
import java.net.Proxy;
7+
import java.net.Proxy.Type;
58
import java.util.Optional;
69
import java.util.function.Function;
710
import java.util.function.Supplier;
@@ -61,6 +64,12 @@ public Supplier<EmbeddingModel> embeddingModel(String configName) {
6164
.logRequests(firstOrDefault(false, embeddingModelConfig.logRequests(), vertexAiConfig.logRequests()))
6265
.logResponses(firstOrDefault(false, embeddingModelConfig.logResponses(), vertexAiConfig.logResponses()));
6366

67+
vertexAiConfig.proxyHost().ifPresent(host -> {
68+
builder.proxy(new Proxy(
69+
Type.valueOf(vertexAiConfig.proxyType()),
70+
new InetSocketAddress(host, vertexAiConfig.proxyPort())));
71+
});
72+
6473
if (embeddingModelConfig.outputDimension().isPresent()) {
6574
builder.dimension(embeddingModelConfig.outputDimension().get());
6675
}
@@ -100,6 +109,12 @@ public Function<SyntheticCreationalContext<ChatModel>, ChatModel> chatModel(Stri
100109
.logRequests(firstOrDefault(false, chatModelConfig.logRequests(), vertexAiConfig.logRequests()))
101110
.logResponses(firstOrDefault(false, chatModelConfig.logResponses(), vertexAiConfig.logResponses()));
102111

112+
vertexAiConfig.proxyHost().ifPresent(host -> {
113+
builder.proxy(new Proxy(
114+
Type.valueOf(vertexAiConfig.proxyType()),
115+
new InetSocketAddress(host, vertexAiConfig.proxyPort())));
116+
});
117+
103118
if (chatModelConfig.temperature().isPresent()) {
104119
builder.temperature(chatModelConfig.temperature().getAsDouble());
105120
}
@@ -159,6 +174,12 @@ public Function<SyntheticCreationalContext<StreamingChatModel>, StreamingChatMod
159174
.logRequests(firstOrDefault(false, chatModelConfig.logRequests(), vertexAiConfig.logRequests()))
160175
.logResponses(firstOrDefault(false, chatModelConfig.logResponses(), vertexAiConfig.logResponses()));
161176

177+
vertexAiConfig.proxyHost().ifPresent(host -> {
178+
builder.proxy(new Proxy(
179+
Type.valueOf(vertexAiConfig.proxyType()),
180+
new InetSocketAddress(host, vertexAiConfig.proxyPort())));
181+
});
182+
162183
if (chatModelConfig.temperature().isPresent()) {
163184
builder.temperature(chatModelConfig.temperature().getAsDouble());
164185
}

model-providers/google/vertex-ai-gemini/runtime/src/main/java/io/quarkiverse/langchain4j/vertexai/runtime/gemini/VertexAiGeminiStreamingChatLanguageModel.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.quarkiverse.langchain4j.vertexai.runtime.gemini;
22

3+
import java.net.InetSocketAddress;
4+
import java.net.Proxy;
35
import java.net.URI;
46
import java.net.URISyntaxException;
57
import java.time.Duration;
@@ -44,6 +46,17 @@ private VertexAiGeminiStreamingChatLanguageModel(Builder builder) {
4446
.connectTimeout(builder.timeout.toSeconds(), TimeUnit.SECONDS)
4547
.readTimeout(builder.timeout.toSeconds(), TimeUnit.SECONDS);
4648

49+
if (builder.proxy != null) {
50+
if (builder.proxy.type() != Proxy.Type.HTTP) {
51+
throw new IllegalArgumentException("Only HTTP type proxy is supported");
52+
}
53+
if (!(builder.proxy.address() instanceof InetSocketAddress)) {
54+
throw new IllegalArgumentException("Unsupported proxy type");
55+
}
56+
InetSocketAddress socketAddress = (InetSocketAddress) builder.proxy.address();
57+
restApiBuilder.proxyAddress(socketAddress.getHostName(), socketAddress.getPort());
58+
}
59+
4760
if (builder.logRequests || builder.logResponses) {
4861
restApiBuilder.loggingScope(LoggingScope.REQUEST_RESPONSE);
4962
restApiBuilder.clientLogger(new VertxAiGeminiRestApi.VertxAiClientLogger(builder.logRequests,
@@ -81,6 +94,7 @@ public static final class Builder {
8194
private Boolean logRequests = false;
8295
private Boolean logResponses = false;
8396
private List<ChatModelListener> listeners = Collections.emptyList();
97+
private Proxy proxy;
8498

8599
public Builder baseUrl(Optional<String> baseUrl) {
86100
this.baseUrl = baseUrl;
@@ -152,6 +166,11 @@ public Builder listeners(List<ChatModelListener> listeners) {
152166
return this;
153167
}
154168

169+
public Builder proxy(Proxy proxy) {
170+
this.proxy = proxy;
171+
return this;
172+
}
173+
155174
public VertexAiGeminiStreamingChatLanguageModel build() {
156175
return new VertexAiGeminiStreamingChatLanguageModel(this);
157176
}

model-providers/google/vertex-ai-gemini/runtime/src/main/java/io/quarkiverse/langchain4j/vertexai/runtime/gemini/config/LangChain4jVertexAiGeminiConfig.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,23 @@ interface VertexAiGeminiConfig {
6868
@WithDefault("true")
6969
Boolean enableIntegration();
7070

71+
/**
72+
* The Proxy type
73+
*/
74+
@WithDefault("HTTP")
75+
String proxyType();
76+
77+
/**
78+
* The Proxy host
79+
*/
80+
Optional<String> proxyHost();
81+
82+
/**
83+
* The Proxy port
84+
*/
85+
@WithDefault("3128")
86+
Integer proxyPort();
87+
7188
/**
7289
* Whether the Vertex AI client should log requests
7390
*/

model-providers/google/vertex-ai/runtime/src/main/java/io/quarkiverse/langchain4j/vertexai/runtime/VertexAiChatLanguageModel.java

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
import static java.util.stream.Collectors.joining;
77
import static java.util.stream.Collectors.toList;
88

9+
import java.net.InetSocketAddress;
10+
import java.net.Proxy;
911
import java.net.URI;
1012
import java.net.URISyntaxException;
1113
import java.time.Duration;
@@ -54,6 +56,17 @@ private VertexAiChatLanguageModel(Builder builder) {
5456
.connectTimeout(builder.timeout.toSeconds(), TimeUnit.SECONDS)
5557
.readTimeout(builder.timeout.toSeconds(), TimeUnit.SECONDS);
5658

59+
if (builder.proxy != null) {
60+
if (builder.proxy.type() != Proxy.Type.HTTP) {
61+
throw new IllegalArgumentException("Only HTTP type proxy is supported");
62+
}
63+
if (!(builder.proxy.address() instanceof InetSocketAddress)) {
64+
throw new IllegalArgumentException("Unsupported proxy type");
65+
}
66+
InetSocketAddress socketAddress = (InetSocketAddress) builder.proxy.address();
67+
restApiBuilder.proxyAddress(socketAddress.getHostName(), socketAddress.getPort());
68+
}
69+
5770
if (builder.logRequests || builder.logResponses) {
5871
restApiBuilder.loggingScope(LoggingScope.REQUEST_RESPONSE);
5972
restApiBuilder.clientLogger(new VertxAiRestApi.VertxAiClientLogger(builder.logRequests,
@@ -115,6 +128,7 @@ public static final class Builder {
115128
private Duration timeout = Duration.ofSeconds(10);
116129
private Boolean logRequests = false;
117130
private Boolean logResponses = false;
131+
private Proxy proxy;
118132

119133
public Builder baseUrl(Optional<String> baseUrl) {
120134
this.baseUrl = baseUrl;
@@ -176,6 +190,11 @@ public Builder logResponses(boolean logResponses) {
176190
return this;
177191
}
178192

193+
public Builder proxy(Proxy proxy) {
194+
this.proxy = proxy;
195+
return this;
196+
}
197+
179198
public VertexAiChatLanguageModel build() {
180199
return new VertexAiChatLanguageModel(this);
181200
}

model-providers/google/vertex-ai/runtime/src/main/java/io/quarkiverse/langchain4j/vertexai/runtime/VertexAiRecorder.java

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

33
import static io.quarkiverse.langchain4j.runtime.OptionalUtil.firstOrDefault;
44

5+
import java.net.InetSocketAddress;
6+
import java.net.Proxy;
7+
import java.net.Proxy.Type;
58
import java.util.Optional;
69
import java.util.function.Supplier;
710

@@ -51,6 +54,12 @@ public Supplier<ChatModel> chatModel(String configName) {
5154
.logRequests(firstOrDefault(false, chatModelConfig.logRequests(), vertexAiConfig.logRequests()))
5255
.logResponses(firstOrDefault(false, chatModelConfig.logResponses(), vertexAiConfig.logResponses()));
5356

57+
vertexAiConfig.proxyHost().ifPresent(host -> {
58+
builder.proxy(new Proxy(
59+
Type.valueOf(vertexAiConfig.proxyType()),
60+
new InetSocketAddress(host, vertexAiConfig.proxyPort())));
61+
});
62+
5463
// TODO: add the rest of the properties
5564

5665
return new Supplier<>() {

model-providers/google/vertex-ai/runtime/src/main/java/io/quarkiverse/langchain4j/vertexai/runtime/config/LangChain4jVertexAiConfig.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,23 @@ interface VertexAiConfig {
6767
@WithDefault("true")
6868
Boolean enableIntegration();
6969

70+
/**
71+
* The Proxy type
72+
*/
73+
@WithDefault("HTTP")
74+
String proxyType();
75+
76+
/**
77+
* The Proxy host
78+
*/
79+
Optional<String> proxyHost();
80+
81+
/**
82+
* The Proxy port
83+
*/
84+
@WithDefault("3128")
85+
Integer proxyPort();
86+
7087
/**
7188
* Whether the Vertex AI client should log requests
7289
*/

model-providers/openai/azure-openai/runtime/src/main/java/io/quarkiverse/langchain4j/azure/openai/runtime/AzureOpenAiRecorder.java

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -89,8 +89,8 @@ public Function<SyntheticCreationalContext<ChatModel>, ChatModel> chatModel(Stri
8989

9090
azureAiConfig.proxyHost().ifPresent(host -> {
9191
builder.proxy(new Proxy(
92-
Type.valueOf(azureAiConfig.proxyType()),
93-
new InetSocketAddress(host, azureAiConfig.proxyPort())));
92+
Type.valueOf(azureAiConfig.proxyType()),
93+
new InetSocketAddress(host, azureAiConfig.proxyPort())));
9494
});
9595
if (chatModelConfig.maxTokens().isPresent()) {
9696
builder.maxTokens(chatModelConfig.maxTokens().get());
@@ -143,8 +143,8 @@ public Function<SyntheticCreationalContext<StreamingChatModel>, StreamingChatMod
143143

144144
azureAiConfig.proxyHost().ifPresent(host -> {
145145
builder.proxy(new Proxy(
146-
Type.valueOf(azureAiConfig.proxyType()),
147-
new InetSocketAddress(host, azureAiConfig.proxyPort())));
146+
Type.valueOf(azureAiConfig.proxyType()),
147+
new InetSocketAddress(host, azureAiConfig.proxyPort())));
148148
});
149149

150150
if (chatModelConfig.maxTokens().isPresent()) {
@@ -192,8 +192,8 @@ public Function<SyntheticCreationalContext<EmbeddingModel>, EmbeddingModel> embe
192192

193193
azureAiConfig.proxyHost().ifPresent(host -> {
194194
builder.proxy(new Proxy(
195-
Type.valueOf(azureAiConfig.proxyType()),
196-
new InetSocketAddress(host, azureAiConfig.proxyPort())));
195+
Type.valueOf(azureAiConfig.proxyType()),
196+
new InetSocketAddress(host, azureAiConfig.proxyPort())));
197197
});
198198

199199
return new Function<>() {

model-providers/openai/azure-openai/runtime/src/test/java/io/quarkiverse/langchain4j/azure/openai/runtime/AzureOpenAiRecorderEndpointTests.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,21 @@ public Boolean enableIntegration() {
196196
return null;
197197
}
198198

199+
@Override
200+
public String proxyType() {
201+
return "HTTP";
202+
}
203+
204+
@Override
205+
public Optional<String> proxyHost() {
206+
return Optional.empty();
207+
}
208+
209+
@Override
210+
public Integer proxyPort() {
211+
return 0;
212+
}
213+
199214
@Override
200215
public ChatModelConfig chatModel() {
201216
return new ChatModelConfig() {

0 commit comments

Comments
 (0)