[FEATURE] Adds SearchApi as WebSearchEngine and Tool (#1216)
This commit is contained in:
parent
99ed696f05
commit
2e47b126be
|
@ -15,14 +15,14 @@ Add the following dependencies to your project's `pom.xml`:
|
|||
<dependency>
|
||||
<groupId>dev.langchain4j</groupId>
|
||||
<artifactId>langchain4j-web-search-engine-searchapi</artifactId>
|
||||
<version>{your-version}</version> <!-- Specify langchain4j version here -->
|
||||
<version>0.34.0</version>
|
||||
</dependency>
|
||||
```
|
||||
|
||||
or project's `build.gradle`:
|
||||
|
||||
```groovy
|
||||
implementation 'dev.langchain4j:langchain4j-web-search-engine-searchapi:{your-version}'
|
||||
implementation 'dev.langchain4j:langchain4j-web-search-engine-searchapi:0.34.0'
|
||||
```
|
||||
|
||||
### Example code:
|
||||
|
@ -40,7 +40,7 @@ import dev.langchain4j.web.search.searchapi.SearchApiWebSearchEngine;
|
|||
public class SearchApiTool {
|
||||
|
||||
interface Assistant {
|
||||
@dev.langchain4j.service.SystemMessage({
|
||||
@SystemMessage({
|
||||
"You are a web search support agent.",
|
||||
"If there is any event that has not happened yet",
|
||||
"You MUST create a web search request with user query and",
|
||||
|
|
|
@ -11,12 +11,14 @@ import java.security.MessageDigest;
|
|||
import java.security.NoSuchAlgorithmException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static java.net.HttpURLConnection.HTTP_OK;
|
||||
import static java.nio.charset.StandardCharsets.UTF_8;
|
||||
import static java.util.Collections.unmodifiableList;
|
||||
import static java.util.Collections.unmodifiableMap;
|
||||
|
||||
/**
|
||||
* Utility methods.
|
||||
|
@ -273,4 +275,20 @@ public class Utils {
|
|||
|
||||
return unmodifiableList(list);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns an (unmodifiable) copy of the provided map.
|
||||
* Returns <code>null</code> if the provided map is <code>null</code>.
|
||||
*
|
||||
* @param map The map to copy.
|
||||
* @return The copy of the provided map.
|
||||
*/
|
||||
public static <K,V> Map<K,V> copyIfNotNull(Map<K,V> map) {
|
||||
if (map == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return unmodifiableMap(map);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,17 +9,13 @@ import org.junit.jupiter.params.provider.MethodSource;
|
|||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.UUID;
|
||||
import java.util.*;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static dev.langchain4j.internal.Utils.quoted;
|
||||
import static java.util.Arrays.asList;
|
||||
import static java.util.Collections.emptyList;
|
||||
import static java.util.Collections.singletonList;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
|
||||
import static java.util.Collections.*;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
@SuppressWarnings({"ObviousNullCheck", "ConstantValue"})
|
||||
class UtilsTest {
|
||||
|
@ -215,13 +211,20 @@ class UtilsTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void test_copyIfNotNull() {
|
||||
assertThat(Utils.copyIfNotNull(null)).isNull();
|
||||
void test_copyIfNotNull_List() {
|
||||
assertThat(Utils.copyIfNotNull((List<?>) null)).isNull();
|
||||
assertThat(Utils.copyIfNotNull(emptyList())).isEmpty();
|
||||
assertThat(Utils.copyIfNotNull(singletonList("one"))).containsExactly("one");
|
||||
assertThat(Utils.copyIfNotNull(asList("one", "two"))).containsExactly("one", "two");
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_copyIfNotNull_Map() {
|
||||
assertThat(Utils.copyIfNotNull((Map<?, ?>)null)).isNull();
|
||||
assertThat(Utils.copyIfNotNull(emptyMap())).isEmpty();
|
||||
assertThat(Utils.copyIfNotNull(singletonMap("key", "value"))).containsExactly(entry("key", "value"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void test_ensureTrailingForwardSlash() {
|
||||
assertThat(Utils.ensureTrailingForwardSlash("https://example.com")).isEqualTo("https://example.com/");
|
||||
|
|
|
@ -9,7 +9,7 @@ import java.util.Map;
|
|||
|
||||
interface SearchApi {
|
||||
|
||||
@GET("/api/v1/search")
|
||||
@GET("api/v1/search")
|
||||
Call<SearchApiWebSearchResponse> search(@QueryMap Map<String, Object> params,
|
||||
@Header("Authorization") String bearerToken);
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import static dev.langchain4j.internal.Utils.copyIfNotNull;
|
||||
import static dev.langchain4j.internal.Utils.getOrDefault;
|
||||
import static dev.langchain4j.internal.ValidationUtils.ensureNotBlank;
|
||||
import static java.time.Duration.ofSeconds;
|
||||
|
@ -25,7 +26,7 @@ import static java.time.Duration.ofSeconds;
|
|||
*/
|
||||
public class SearchApiWebSearchEngine implements WebSearchEngine {
|
||||
|
||||
private static final String BASE_URL = "https://www.searchapi.io";
|
||||
private static final String DEFAULT_BASE_URL = "https://www.searchapi.io";
|
||||
private static final String DEFAULT_ENGINE = "google";
|
||||
|
||||
private final String apiKey;
|
||||
|
@ -54,10 +55,10 @@ public class SearchApiWebSearchEngine implements WebSearchEngine {
|
|||
Map<String, Object> optionalParameters) {
|
||||
this.apiKey = ensureNotBlank(apiKey, "apiKey");
|
||||
this.engine = getOrDefault(engine, DEFAULT_ENGINE);
|
||||
this.optionalParameters = getOrDefault(optionalParameters, new HashMap<>());
|
||||
this.optionalParameters = getOrDefault(copyIfNotNull(optionalParameters), new HashMap<>());
|
||||
this.client = SearchApiClient.builder()
|
||||
.timeout(getOrDefault(timeout, ofSeconds(30)))
|
||||
.baseUrl(getOrDefault(baseUrl, BASE_URL))
|
||||
.baseUrl(getOrDefault(baseUrl, DEFAULT_BASE_URL))
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ package dev.langchain4j.web.search.searchapi;
|
|||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@Getter
|
||||
|
@ -25,7 +26,7 @@ class SearchApiWebSearchRequest {
|
|||
this.engine = engine;
|
||||
this.apiKey = apiKey;
|
||||
this.query = query;
|
||||
this.finalOptionalParameters = optionalParameters;
|
||||
this.finalOptionalParameters = new HashMap<>(optionalParameters);
|
||||
if (additionalRequestParameters != null) {
|
||||
finalOptionalParameters.putAll(additionalRequestParameters);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue