Skip to content

Commit c361c1e

Browse files
committed
Add Cloud Bindings for Mistral AI
* Introduce Cloud Bindings support to configure the Mistral AI integration * Update the Cloud Bindings documentation accordingly
1 parent 2babb2a commit c361c1e

File tree

4 files changed

+121
-1
lines changed

4 files changed

+121
-1
lines changed

spring-ai-docs/src/main/antora/modules/ROOT/pages/api/cloud-bindings.adoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ Configuration for `api-key`, `uri`, `username`, `password`, etc. can be specifie
1212

1313
To enable cloud binding support, include the following dependency in the application.
1414

15-
1615
[source,xml]
1716
----
1817
<dependency>
@@ -42,6 +41,9 @@ The following are the components for which the cloud binding support is currentl
4241
| `Chroma Vecor Store`
4342
| `chroma` | `uri`, `username`, `passwor` | `spring.ai.vectorstore.chroma.client.host`, `spring.ai.vectorstore.chroma.client.port`, `spring.ai.vectorstore.chroma.client.username`, `spring.ai.vectorstore.chroma.client.host.password`
4443

44+
| `Mistral AI`
45+
| `mistralai` | `api-key`, `uri` | `spring.ai.mistralai.api-key`, `spring.ai.mistralai.base-url`
46+
4547
| `Ollama`
4648
| `ollama` | `uri` | `spring.ai.ollama.base-url`
4749

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright 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.bindings;
18+
19+
import org.springframework.cloud.bindings.Binding;
20+
import org.springframework.cloud.bindings.Bindings;
21+
import org.springframework.cloud.bindings.boot.BindingsPropertiesProcessor;
22+
import org.springframework.core.env.Environment;
23+
24+
import java.util.Map;
25+
26+
/**
27+
* An implementation of {@link BindingsPropertiesProcessor} that detects {@link Binding}s
28+
* of type: {@value TYPE}.
29+
*
30+
* @author Thomas Vitale
31+
*/
32+
public class MistralAiBindingsPropertiesProcessor implements BindingsPropertiesProcessor {
33+
34+
/**
35+
* The {@link Binding} type that this processor is interested in: {@value}.
36+
**/
37+
public static final String TYPE = "mistralai";
38+
39+
@Override
40+
public void process(Environment environment, Bindings bindings, Map<String, Object> properties) {
41+
if (!BindingsValidator.isTypeEnabled(environment, TYPE)) {
42+
return;
43+
}
44+
45+
bindings.filterBindings(TYPE).forEach(binding -> {
46+
properties.put("spring.ai.mistralai.api-key", binding.getSecret().get("api-key"));
47+
properties.put("spring.ai.mistralai.base-url", binding.getSecret().get("uri"));
48+
});
49+
}
50+
51+
}

spring-ai-spring-cloud-bindings/src/main/resources/META-INF/spring.factories

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# Binding Properties Factories
22
org.springframework.cloud.bindings.boot.BindingsPropertiesProcessor=\
33
org.springframework.ai.bindings.ChromaBindingsPropertiesProcessor,\
4+
org.springframework.ai.bindings.MistralAiBindingsPropertiesProcessor,\
45
org.springframework.ai.bindings.OllamaBindingsPropertiesProcessor,\
56
org.springframework.ai.bindings.OpenAiBindingsPropertiesProcessor,\
67
org.springframework.ai.bindings.TanzuBindingsPropertiesProcessor,\
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
* Copyright 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.bindings;
18+
19+
import org.junit.jupiter.api.Test;
20+
import org.springframework.cloud.bindings.Binding;
21+
import org.springframework.cloud.bindings.Bindings;
22+
import org.springframework.mock.env.MockEnvironment;
23+
24+
import java.nio.file.Paths;
25+
import java.util.HashMap;
26+
import java.util.Map;
27+
28+
import static org.assertj.core.api.Assertions.assertThat;
29+
import static org.springframework.ai.bindings.BindingsValidator.CONFIG_PATH;
30+
31+
/**
32+
* Unit tests for {@link MistralAiBindingsPropertiesProcessor}.
33+
*
34+
* @author Thomas Vitale
35+
*/
36+
class MistralAiBindingsPropertiesProcessorTests {
37+
38+
private final Bindings bindings = new Bindings(new Binding("test-name", Paths.get("test-path"),
39+
// @formatter:off
40+
Map.of(
41+
Binding.TYPE, MistralAiBindingsPropertiesProcessor.TYPE,
42+
"api-key", "demo",
43+
"uri", "https://my.mistralai.example.net"
44+
)));
45+
// @formatter:on
46+
47+
private final MockEnvironment environment = new MockEnvironment();
48+
49+
private final Map<String, Object> properties = new HashMap<>();
50+
51+
@Test
52+
void propertiesAreContributed() {
53+
new MistralAiBindingsPropertiesProcessor().process(environment, bindings, properties);
54+
assertThat(properties).containsEntry("spring.ai.mistralai.api-key", "demo");
55+
assertThat(properties).containsEntry("spring.ai.mistralai.base-url", "https://my.mistralai.example.net");
56+
}
57+
58+
@Test
59+
void whenDisabledThenPropertiesAreNotContributed() {
60+
environment.setProperty("%s.mistralai.enabled".formatted(CONFIG_PATH), "false");
61+
62+
new MistralAiBindingsPropertiesProcessor().process(environment, bindings, properties);
63+
assertThat(properties).isEmpty();
64+
}
65+
66+
}

0 commit comments

Comments
 (0)