Skip to content

Commit a322cc6

Browse files
markpollackscionaltera
authored andcommitted
Revert "Merge remote-tracking branch 'upstream/main'"
This reverts commit e954045, reversing changes made to f17dfa1.
1 parent 8ce4eee commit a322cc6

File tree

12 files changed

+2
-1029
lines changed

12 files changed

+2
-1029
lines changed

advisors/spring-ai-advisors-vector-store/src/test/java/org/springframework/ai/chat/client/advisor/vectorstore/QuestionAnswerAdvisorTests.java

Lines changed: 0 additions & 159 deletions
Original file line numberDiff line numberDiff line change
@@ -243,163 +243,4 @@ public void qaAdvisorTakesUserParameterizedUserMessagesIntoAccountForSimilarityS
243243
Assertions.assertThat(this.vectorSearchCaptor.getValue().getQuery()).isEqualTo(expectedQuery);
244244
}
245245

246-
@Test
247-
public void qaAdvisorWithMultipleFilterParameters() {
248-
given(this.chatModel.call(this.promptCaptor.capture()))
249-
.willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("Filtered response"))),
250-
ChatResponseMetadata.builder().build()));
251-
252-
given(this.vectorStore.similaritySearch(this.vectorSearchCaptor.capture()))
253-
.willReturn(List.of(new Document("doc1"), new Document("doc2")));
254-
255-
var qaAdvisor = QuestionAnswerAdvisor.builder(this.vectorStore)
256-
.searchRequest(SearchRequest.builder().topK(10).build())
257-
.build();
258-
259-
var chatClient = ChatClient.builder(this.chatModel)
260-
.defaultAdvisors(qaAdvisor)
261-
.build();
262-
263-
chatClient.prompt()
264-
.user("Complex query")
265-
.advisors(a -> a.param(QuestionAnswerAdvisor.FILTER_EXPRESSION, "type == 'Documentation' AND status == 'Published'"))
266-
.call()
267-
.chatResponse();
268-
269-
var capturedFilter = this.vectorSearchCaptor.getValue().getFilterExpression();
270-
assertThat(capturedFilter).isNotNull();
271-
// The filter should be properly constructed with AND operation
272-
assertThat(capturedFilter.toString()).contains("type");
273-
assertThat(capturedFilter.toString()).contains("Documentation");
274-
}
275-
276-
@Test
277-
public void qaAdvisorWithDifferentSimilarityThresholds() {
278-
given(this.chatModel.call(this.promptCaptor.capture()))
279-
.willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("High threshold response"))),
280-
ChatResponseMetadata.builder().build()));
281-
282-
given(this.vectorStore.similaritySearch(this.vectorSearchCaptor.capture()))
283-
.willReturn(List.of(new Document("relevant doc")));
284-
285-
var qaAdvisor = QuestionAnswerAdvisor.builder(this.vectorStore)
286-
.searchRequest(SearchRequest.builder().similarityThreshold(0.95).topK(3).build())
287-
.build();
288-
289-
var chatClient = ChatClient.builder(this.chatModel)
290-
.defaultAdvisors(qaAdvisor)
291-
.build();
292-
293-
chatClient.prompt()
294-
.user("Specific question requiring high similarity")
295-
.call()
296-
.chatResponse();
297-
298-
assertThat(this.vectorSearchCaptor.getValue().getSimilarityThreshold()).isEqualTo(0.95);
299-
assertThat(this.vectorSearchCaptor.getValue().getTopK()).isEqualTo(3);
300-
}
301-
302-
@Test
303-
public void qaAdvisorWithComplexParameterizedTemplate() {
304-
given(this.chatModel.call(this.promptCaptor.capture()))
305-
.willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("Complex template response"))),
306-
ChatResponseMetadata.builder().build()));
307-
308-
given(this.vectorStore.similaritySearch(this.vectorSearchCaptor.capture()))
309-
.willReturn(List.of(new Document("template doc")));
310-
311-
var qaAdvisor = QuestionAnswerAdvisor.builder(this.vectorStore)
312-
.searchRequest(SearchRequest.builder().build())
313-
.build();
314-
315-
var chatClient = ChatClient.builder(this.chatModel)
316-
.defaultAdvisors(qaAdvisor)
317-
.build();
318-
319-
var complexTemplate = "Please analyze {topic} considering {aspect1} and {aspect2} for user {userId}";
320-
chatClient.prompt()
321-
.user(u -> u.text(complexTemplate)
322-
.param("topic", "machine learning")
323-
.param("aspect1", "performance")
324-
.param("aspect2", "scalability")
325-
.param("userId", "user1"))
326-
.call()
327-
.chatResponse();
328-
329-
var expectedQuery = "Please analyze machine learning considering performance and scalability for user user1";
330-
assertThat(this.vectorSearchCaptor.getValue().getQuery()).isEqualTo(expectedQuery);
331-
332-
Message userMessage = this.promptCaptor.getValue().getInstructions().get(0);
333-
assertThat(userMessage.getText()).contains(expectedQuery);
334-
assertThat(userMessage.getText()).doesNotContain("{topic}");
335-
assertThat(userMessage.getText()).doesNotContain("{aspect1}");
336-
assertThat(userMessage.getText()).doesNotContain("{aspect2}");
337-
assertThat(userMessage.getText()).doesNotContain("{userId}");
338-
}
339-
340-
@Test
341-
public void qaAdvisorWithDocumentsContainingMetadata() {
342-
given(this.chatModel.call(this.promptCaptor.capture()))
343-
.willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("Metadata response"))),
344-
ChatResponseMetadata.builder().build()));
345-
346-
var docWithMetadata1 = new Document("First document content", Map.of("source", "wiki", "author", "John"));
347-
var docWithMetadata2 = new Document("Second document content", Map.of("source", "manual", "version", "2.1"));
348-
349-
given(this.vectorStore.similaritySearch(this.vectorSearchCaptor.capture()))
350-
.willReturn(List.of(docWithMetadata1, docWithMetadata2));
351-
352-
var qaAdvisor = QuestionAnswerAdvisor.builder(this.vectorStore)
353-
.searchRequest(SearchRequest.builder().topK(2).build())
354-
.build();
355-
356-
var chatClient = ChatClient.builder(this.chatModel)
357-
.defaultAdvisors(qaAdvisor)
358-
.build();
359-
360-
chatClient.prompt()
361-
.user("Question about documents with metadata")
362-
.call()
363-
.chatResponse();
364-
365-
Message userMessage = this.promptCaptor.getValue().getInstructions().get(0);
366-
assertThat(userMessage.getText()).contains("First document content");
367-
assertThat(userMessage.getText()).contains("Second document content");
368-
}
369-
370-
@Test
371-
public void qaAdvisorBuilderValidation() {
372-
// Test that builder validates required parameters
373-
Assertions.assertThatThrownBy(() -> QuestionAnswerAdvisor.builder(null))
374-
.isInstanceOf(IllegalArgumentException.class);
375-
376-
// Test successful builder creation
377-
var advisor = QuestionAnswerAdvisor.builder(this.vectorStore).build();
378-
assertThat(advisor).isNotNull();
379-
}
380-
381-
@Test
382-
public void qaAdvisorWithZeroTopK() {
383-
given(this.chatModel.call(this.promptCaptor.capture()))
384-
.willReturn(new ChatResponse(List.of(new Generation(new AssistantMessage("Zero docs response"))),
385-
ChatResponseMetadata.builder().build()));
386-
387-
given(this.vectorStore.similaritySearch(this.vectorSearchCaptor.capture()))
388-
.willReturn(List.of());
389-
390-
var qaAdvisor = QuestionAnswerAdvisor.builder(this.vectorStore)
391-
.searchRequest(SearchRequest.builder().topK(0).build())
392-
.build();
393-
394-
var chatClient = ChatClient.builder(this.chatModel)
395-
.defaultAdvisors(qaAdvisor)
396-
.build();
397-
398-
chatClient.prompt()
399-
.user("Question with zero topK")
400-
.call()
401-
.chatResponse();
402-
403-
assertThat(this.vectorSearchCaptor.getValue().getTopK()).isEqualTo(0);
404-
}
405246
}

advisors/spring-ai-advisors-vector-store/src/test/java/org/springframework/ai/chat/client/advisor/vectorstore/VectorStoreChatMemoryAdvisorTests.java

Lines changed: 0 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -216,155 +216,4 @@ void whenBuilderWithCustomSystemPromptTemplateThenSuccess() {
216216
assertThat(advisor).isNotNull();
217217
}
218218

219-
@Test
220-
void whenBuilderWithEmptyStringConversationIdThenThrow() {
221-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
222-
223-
assertThatThrownBy(() -> VectorStoreChatMemoryAdvisor.builder(vectorStore).conversationId("").build())
224-
.isInstanceOf(IllegalArgumentException.class)
225-
.hasMessageContaining("defaultConversationId cannot be null or empty");
226-
}
227-
228-
@Test
229-
void whenBuilderWithWhitespaceOnlyConversationIdThenThrow() {
230-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
231-
232-
assertThatThrownBy(() -> VectorStoreChatMemoryAdvisor.builder(vectorStore).conversationId("\t\n\r ").build())
233-
.isInstanceOf(IllegalArgumentException.class)
234-
.hasMessageContaining("defaultConversationId cannot be null or empty");
235-
}
236-
237-
@Test
238-
void whenBuilderWithSpecialCharactersInConversationIdThenSuccess() {
239-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
240-
241-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
242-
.conversationId("[email protected]")
243-
.build();
244-
245-
assertThat(advisor).isNotNull();
246-
}
247-
248-
@Test
249-
void whenBuilderWithMaxIntegerTopKThenSuccess() {
250-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
251-
252-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
253-
.defaultTopK(Integer.MAX_VALUE)
254-
.build();
255-
256-
assertThat(advisor).isNotNull();
257-
}
258-
259-
@Test
260-
void whenBuilderWithNegativeTopKThenThrow() {
261-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
262-
263-
assertThatThrownBy(() -> VectorStoreChatMemoryAdvisor.builder(vectorStore).defaultTopK(-100).build())
264-
.isInstanceOf(IllegalArgumentException.class)
265-
.hasMessageContaining("topK must be greater than 0");
266-
}
267-
268-
@Test
269-
void whenBuilderChainedWithAllParametersThenSuccess() {
270-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
271-
Scheduler scheduler = Mockito.mock(Scheduler.class);
272-
PromptTemplate systemPromptTemplate = Mockito.mock(PromptTemplate.class);
273-
274-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
275-
.conversationId("chained-test")
276-
.defaultTopK(42)
277-
.scheduler(scheduler)
278-
.systemPromptTemplate(systemPromptTemplate)
279-
.build();
280-
281-
assertThat(advisor).isNotNull();
282-
}
283-
284-
@Test
285-
void whenBuilderParametersSetInDifferentOrderThenSuccess() {
286-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
287-
Scheduler scheduler = Mockito.mock(Scheduler.class);
288-
PromptTemplate systemPromptTemplate = Mockito.mock(PromptTemplate.class);
289-
290-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
291-
.systemPromptTemplate(systemPromptTemplate)
292-
.defaultTopK(7)
293-
.scheduler(scheduler)
294-
.conversationId("order-test")
295-
.build();
296-
297-
assertThat(advisor).isNotNull();
298-
}
299-
300-
@Test
301-
void whenBuilderWithOverriddenParametersThenUseLastValue() {
302-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
303-
304-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
305-
.conversationId("first-id")
306-
.conversationId("second-id") // This should override the first
307-
.defaultTopK(5)
308-
.defaultTopK(10) // This should override the first
309-
.build();
310-
311-
assertThat(advisor).isNotNull();
312-
}
313-
314-
@Test
315-
void whenBuilderReusedThenCreatesSeparateInstances() {
316-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
317-
318-
// Simulate builder reuse (if the builder itself is stateful)
319-
var builder = VectorStoreChatMemoryAdvisor.builder(vectorStore).conversationId("shared-config");
320-
321-
VectorStoreChatMemoryAdvisor advisor1 = builder.build();
322-
VectorStoreChatMemoryAdvisor advisor2 = builder.build();
323-
324-
assertThat(advisor1).isNotNull();
325-
assertThat(advisor2).isNotNull();
326-
assertThat(advisor1).isNotSameAs(advisor2);
327-
}
328-
329-
@Test
330-
void whenBuilderWithLongConversationIdThenSuccess() {
331-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
332-
String longId = "a".repeat(1000); // 1000 character conversation ID
333-
334-
VectorStoreChatMemoryAdvisor advisor = VectorStoreChatMemoryAdvisor.builder(vectorStore)
335-
.conversationId(longId)
336-
.build();
337-
338-
assertThat(advisor).isNotNull();
339-
}
340-
341-
@Test
342-
void whenBuilderCalledWithNullAfterValidValueThenThrow() {
343-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
344-
345-
assertThatThrownBy(() -> VectorStoreChatMemoryAdvisor.builder(vectorStore)
346-
.conversationId("valid-id")
347-
.conversationId(null) // Set to null after valid value
348-
.build()).isInstanceOf(IllegalArgumentException.class)
349-
.hasMessageContaining("defaultConversationId cannot be null or empty");
350-
}
351-
352-
@Test
353-
void whenBuilderWithTopKBoundaryValuesThenSuccess() {
354-
VectorStore vectorStore = Mockito.mock(VectorStore.class);
355-
356-
// Test with value 1 (minimum valid)
357-
VectorStoreChatMemoryAdvisor advisor1 = VectorStoreChatMemoryAdvisor.builder(vectorStore)
358-
.defaultTopK(1)
359-
.build();
360-
361-
// Test with a reasonable upper bound
362-
VectorStoreChatMemoryAdvisor advisor2 = VectorStoreChatMemoryAdvisor.builder(vectorStore)
363-
.defaultTopK(10000)
364-
.build();
365-
366-
assertThat(advisor1).isNotNull();
367-
assertThat(advisor2).isNotNull();
368-
}
369-
370219
}

models/spring-ai-google-genai/src/test/java/org/springframework/ai/google/genai/MimeTypeDetectorTests.java

Lines changed: 1 addition & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -26,13 +26,11 @@
2626
import org.junit.jupiter.params.provider.Arguments;
2727
import org.junit.jupiter.params.provider.MethodSource;
2828

29-
import org.junit.jupiter.params.provider.ValueSource;
29+
import org.springframework.ai.google.genai.MimeTypeDetector;
3030
import org.springframework.core.io.PathResource;
3131
import org.springframework.util.MimeType;
3232

3333
import static org.assertj.core.api.Assertions.assertThat;
34-
import static org.assertj.core.api.AssertionsForClassTypes.assertThatCode;
35-
import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy;
3634
import static org.springframework.ai.google.genai.MimeTypeDetector.GEMINI_MIME_TYPES;
3735

3836
/**
@@ -92,49 +90,4 @@ void getMimeTypeByString(String extension, MimeType expectedMimeType) {
9290
assertThat(mimeType).isEqualTo(expectedMimeType);
9391
}
9492

95-
@ParameterizedTest
96-
@ValueSource(strings = { " ", "\t", "\n" })
97-
void getMimeTypeByStringWithInvalidInputShouldThrowException(String invalidPath) {
98-
assertThatThrownBy(() -> MimeTypeDetector.getMimeType(invalidPath)).isInstanceOf(IllegalArgumentException.class)
99-
.hasMessageContaining("Unable to detect the MIME type");
100-
}
101-
102-
@ParameterizedTest
103-
@ValueSource(strings = { "JPG", "PNG", "GIF" })
104-
void getMimeTypeByStringWithUppercaseExtensionsShouldWork(String uppercaseExt) {
105-
String upperFileName = "test." + uppercaseExt;
106-
String lowerFileName = "test." + uppercaseExt.toLowerCase();
107-
108-
// Should throw for uppercase (not in map) but work for lowercase
109-
assertThatThrownBy(() -> MimeTypeDetector.getMimeType(upperFileName))
110-
.isInstanceOf(IllegalArgumentException.class);
111-
112-
// Lowercase should work if it's a supported extension
113-
if (GEMINI_MIME_TYPES.containsKey(uppercaseExt.toLowerCase())) {
114-
assertThatCode(() -> MimeTypeDetector.getMimeType(lowerFileName)).doesNotThrowAnyException();
115-
}
116-
}
117-
118-
@ParameterizedTest
119-
@ValueSource(strings = { "test.jpg", "test.png", "test.gif" })
120-
void getMimeTypeSupportedFileAcrossDifferentMethodsShouldBeConsistent(String fileName) {
121-
MimeType stringResult = MimeTypeDetector.getMimeType(fileName);
122-
MimeType fileResult = MimeTypeDetector.getMimeType(new File(fileName));
123-
MimeType pathResult = MimeTypeDetector.getMimeType(Path.of(fileName));
124-
125-
// All methods should return the same result for supported extensions
126-
assertThat(stringResult).isEqualTo(fileResult);
127-
assertThat(stringResult).isEqualTo(pathResult);
128-
}
129-
130-
@ParameterizedTest
131-
@ValueSource(strings = { "https://example.com/documents/file.pdf", "https://example.com/data/file.json",
132-
"https://example.com/files/document.txt" })
133-
void getMimeTypeByURIWithUnsupportedExtensionsShouldThrowException(String url) {
134-
URI uri = URI.create(url);
135-
136-
assertThatThrownBy(() -> MimeTypeDetector.getMimeType(uri)).isInstanceOf(IllegalArgumentException.class)
137-
.hasMessageContaining("Unable to detect the MIME type");
138-
}
139-
14093
}

0 commit comments

Comments
 (0)