-
-
Notifications
You must be signed in to change notification settings - Fork 95
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add support for TavilySearchResultsTool and TavilyAnswerTool (#467
- Loading branch information
1 parent
7c89060
commit a9f3575
Showing
22 changed files
with
494 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
21 changes: 21 additions & 0 deletions
21
packages/langchain_community/lib/src/tools/tavily/mappers.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
// ignore_for_file: public_member_api_docs | ||
import 'package:tavily_dart/tavily_dart.dart'; | ||
|
||
import 'types.dart'; | ||
|
||
extension TavilySearchDepthX on TavilySearchDepth { | ||
SearchRequestSearchDepth toSearchRequestSearchDepth() => switch (this) { | ||
TavilySearchDepth.basic => SearchRequestSearchDepth.basic, | ||
TavilySearchDepth.advanced => SearchRequestSearchDepth.advanced, | ||
}; | ||
} | ||
|
||
extension TavilySearchResultX on SearchResult { | ||
TavilySearchResult toTavilySearchResult() => TavilySearchResult( | ||
title: title, | ||
url: url, | ||
content: content, | ||
rawContent: rawContent, | ||
score: score, | ||
); | ||
} |
3 changes: 3 additions & 0 deletions
3
packages/langchain_community/lib/src/tools/tavily/tavily.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export 'tavily_answer.dart'; | ||
export 'tavily_search_results.dart'; | ||
export 'types.dart'; |
102 changes: 102 additions & 0 deletions
102
packages/langchain_community/lib/src/tools/tavily/tavily_answer.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
import 'dart:async'; | ||
|
||
import 'package:http/http.dart' as http; | ||
import 'package:langchain_core/tools.dart'; | ||
import 'package:tavily_dart/tavily_dart.dart'; | ||
|
||
import 'mappers.dart'; | ||
import 'tavily_search_results.dart'; | ||
import 'types.dart'; | ||
|
||
/// Tool that queries the [Tavily Search API](https://tavily.com) and | ||
/// gets an answer to the search query. | ||
/// | ||
/// The Tavily API uses API keys for authentication. Visit the | ||
/// [Tavily console](https://app.tavily.com/) to retrieve the API key you'll | ||
/// use in your requests. | ||
/// | ||
/// If you want to get a list of search results instead, use the | ||
/// [TavilySearchResultsTool] instead. | ||
/// | ||
/// Example: | ||
/// ```dart | ||
/// final tool = TavilyAnswerTool( | ||
/// apiKey: Platform.environment['TAVILY_API_KEY']!, | ||
/// ); | ||
/// final res = await tool.invoke('What is the weather like in New York?'); | ||
/// print(res); | ||
/// // The current weather in New York is clear with a temperature of 22.8°C (73.0°F)... | ||
/// ``` | ||
final class TavilyAnswerTool extends StringTool<TavilyAnswerToolOptions> { | ||
/// Creates a [TavilyAnswerTool] instance. | ||
/// | ||
/// Main configuration options: | ||
/// - `apiKey`: your Tavily API key. You can find your API key in the | ||
/// [Tavily console](https://app.tavily.com/). | ||
/// | ||
/// Advance configuration options: | ||
/// - `baseUrl`: the base URL to use. Defaults to Tavily's API URL. You can | ||
/// override this to use a different API URL, or to use a proxy. | ||
/// - `headers`: global headers to send with every request. You can use | ||
/// this to set custom headers, or to override the default headers. | ||
/// - `queryParams`: global query parameters to send with every request. You | ||
/// can use this to set custom query parameters (e.g. Azure OpenAI API | ||
/// required to attach a `version` query parameter to every request). | ||
/// - `client`: the HTTP client to use. You can set your own HTTP client if | ||
/// you need further customization (e.g. to use a Socks5 proxy). | ||
TavilyAnswerTool({ | ||
required this.apiKey, | ||
final String? baseUrl, | ||
final Map<String, String> headers = const {}, | ||
final Map<String, dynamic> queryParams = const {}, | ||
final http.Client? client, | ||
super.defaultOptions = const TavilyAnswerToolOptions(), | ||
}) : _client = TavilyClient( | ||
baseUrl: baseUrl, | ||
headers: headers, | ||
queryParams: queryParams, | ||
client: client, | ||
), | ||
super( | ||
name: 'tavily_answer', | ||
description: | ||
'A search engine optimized for comprehensive, accurate, and trusted answers. ' | ||
'Useful for when you need to answer questions about current events. ' | ||
'The tool returns an answer to the search query - not the search results.', | ||
inputDescription: 'The search query to get an answer to. ' | ||
'Eg: "What is the weather like in New York?"', | ||
); | ||
|
||
/// A client for interacting with Tavily API. | ||
final TavilyClient _client; | ||
|
||
/// Your Tavily API key. | ||
String apiKey; | ||
|
||
@override | ||
Future<String> invokeInternal( | ||
final String toolInput, { | ||
final TavilyAnswerToolOptions? options, | ||
}) async { | ||
final res = await _client.search( | ||
request: SearchRequest( | ||
apiKey: apiKey, | ||
query: toolInput, | ||
includeAnswer: true, | ||
searchDepth: (options?.searchDepth ?? defaultOptions.searchDepth) | ||
.toSearchRequestSearchDepth(), | ||
maxResults: options?.maxResults ?? defaultOptions.maxResults, | ||
includeDomains: | ||
options?.includeDomains ?? defaultOptions.includeDomains, | ||
excludeDomains: | ||
options?.excludeDomains ?? defaultOptions.excludeDomains, | ||
), | ||
); | ||
return res.answer ?? ''; | ||
} | ||
|
||
@override | ||
void close() { | ||
_client.endSession(); | ||
} | ||
} |
130 changes: 130 additions & 0 deletions
130
packages/langchain_community/lib/src/tools/tavily/tavily_search_results.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
import 'dart:async'; | ||
|
||
import 'package:http/http.dart' as http; | ||
import 'package:langchain_core/tools.dart'; | ||
import 'package:tavily_dart/tavily_dart.dart'; | ||
|
||
import 'mappers.dart'; | ||
import 'tavily_answer.dart'; | ||
import 'types.dart'; | ||
|
||
/// Tool that queries the [Tavily Search API](https://tavily.com) and | ||
/// gets back a list of search results. | ||
/// | ||
/// The Tavily API uses API keys for authentication. Visit the | ||
/// [Tavily console](https://app.tavily.com/) to retrieve the API key you'll | ||
/// use in your requests. | ||
/// | ||
/// If you want to get directly an answer to a search query, use the | ||
/// [TavilyAnswerTool] instead. | ||
/// | ||
/// Example: | ||
/// ```dart | ||
/// final tool = TavilySearchResultsTool( | ||
/// apiKey: Platform.environment['TAVILY_API_KEY']!, | ||
/// ); | ||
/// final res = await tool.invoke('What is the weather like in New York?'); | ||
/// print(res); | ||
/// // [ | ||
/// // { | ||
/// // "title": "Weather in New York", | ||
/// // "url": "https://www.weatherapi.com/", | ||
/// // "content": "{'location': {'lat': 40.71, 'lon': -74.01}, 'current': {'last_updated': '2024-06-20 17:00', 'temp_c': 31.1, 'condition': {'text': 'Sunny', 'icon': '//cdn.weatherapi.com/weather/64x64/day/113.png'}, 'wind_mph': 2.2, 'wind_kph': 3.6, 'wind_degree': 161, 'wind_dir': 'SSE', 'pressure_mb': 1025.0, 'pressure_in': 30.26, 'precip_mm': 0.0, 'precip_in': 0.0, 'humidity': 48, 'cloud': 0, 'feelslike_c': 33.1, 'feelslike_f': 91.6, 'windchill_c': 29.5, 'windchill_f': 85.0, 'heatindex_c': 30.6, 'heatindex_f': 87.0, 'dewpoint_c': 17.7, 'dewpoint_f': 63.8, 'vis_km': 16.0, 'vis_miles': 9.0, 'uv': 7.0, 'gust_mph': 16.4, 'gust_kph': 26.4}}", | ||
/// // "score": 0.98855 | ||
/// // }, | ||
/// // ... | ||
/// // ] | ||
/// ``` | ||
final class TavilySearchResultsTool | ||
extends Tool<String, TavilySearchResultsToolOptions, TavilySearchResults> { | ||
/// Creates a [TavilySearchResultsTool] instance. | ||
/// | ||
/// Main configuration options: | ||
/// - `apiKey`: your Tavily API key. You can find your API key in the | ||
/// [Tavily console](https://app.tavily.com/). | ||
/// | ||
/// Advance configuration options: | ||
/// - `baseUrl`: the base URL to use. Defaults to Tavily's API URL. You can | ||
/// override this to use a different API URL, or to use a proxy. | ||
/// - `headers`: global headers to send with every request. You can use | ||
/// this to set custom headers, or to override the default headers. | ||
/// - `queryParams`: global query parameters to send with every request. You | ||
/// can use this to set custom query parameters (e.g. Azure OpenAI API | ||
/// required to attach a `version` query parameter to every request). | ||
/// - `client`: the HTTP client to use. You can set your own HTTP client if | ||
/// you need further customization (e.g. to use a Socks5 proxy). | ||
TavilySearchResultsTool({ | ||
required this.apiKey, | ||
final String? baseUrl, | ||
final Map<String, String> headers = const {}, | ||
final Map<String, dynamic> queryParams = const {}, | ||
final http.Client? client, | ||
super.defaultOptions = const TavilySearchResultsToolOptions(), | ||
}) : _client = TavilyClient( | ||
baseUrl: baseUrl, | ||
headers: headers, | ||
queryParams: queryParams, | ||
client: client, | ||
), | ||
super( | ||
name: 'tavily_search_results', | ||
description: | ||
'A search engine optimized for comprehensive, accurate, and trusted results. ' | ||
'Useful for when you need to answer questions about current events. ' | ||
'The tool returns a JSON object with search results.', | ||
inputJsonSchema: { | ||
'type': 'object', | ||
'properties': { | ||
'query': { | ||
'type': 'string', | ||
'description': 'The search query to look up. ' | ||
'Eg: "What is the weather like in New York?"', | ||
}, | ||
}, | ||
'required': ['query'], | ||
}, | ||
); | ||
|
||
/// A client for interacting with Tavily API. | ||
final TavilyClient _client; | ||
|
||
/// Your Tavily API key. | ||
String apiKey; | ||
|
||
@override | ||
Future<TavilySearchResults> invokeInternal( | ||
final String input, { | ||
final TavilySearchResultsToolOptions? options, | ||
}) async { | ||
final res = await _client.search( | ||
request: SearchRequest( | ||
apiKey: apiKey, | ||
query: input, | ||
searchDepth: (options?.searchDepth ?? defaultOptions.searchDepth) | ||
.toSearchRequestSearchDepth(), | ||
maxResults: options?.maxResults ?? defaultOptions.maxResults, | ||
includeRawContent: | ||
options?.includeRawContent ?? defaultOptions.includeRawContent, | ||
includeDomains: | ||
options?.includeDomains ?? defaultOptions.includeDomains, | ||
excludeDomains: | ||
options?.excludeDomains ?? defaultOptions.excludeDomains, | ||
), | ||
); | ||
return TavilySearchResults( | ||
results: res.results | ||
.map((r) => r.toTavilySearchResult()) | ||
.toList(growable: false), | ||
); | ||
} | ||
|
||
@override | ||
String getInputFromJson(final Map<String, dynamic> json) { | ||
return json['query'] as String; | ||
} | ||
|
||
@override | ||
void close() { | ||
_client.endSession(); | ||
} | ||
} |
Oops, something went wrong.