-
Notifications
You must be signed in to change notification settings - Fork 106
Enable built-in search & fetch tools #829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
hadley
wants to merge
21
commits into
main
Choose a base branch
from
built-in-tools
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
f89d530
Implement built-in tools
hadley 9c24f1b
Merge commit 'f79d57b9a702d39a2e7bbb04a1e94426cb4891d1'
hadley 0c0a264
Move to own files
hadley efdb6e7
Implement request + response types for search + fetch for claude
hadley f5e835d
Merge commit '0c590a5e183c065aa75502d2a89472ab52f6a948'
hadley 7673131
Group all provider specific helpers together
hadley c83821a
Update google docs
hadley 9441fb4
Add content type for openai
hadley 018c342
Rename
hadley ad15423
Use shorter tool names
hadley d7a8fd3
Add test for web fetch and fix problems thus revealed
hadley c7f80e6
Add tests and fix bugs
hadley df11f43
Improve google token counting
hadley b2bd2c6
Polish news bullet
hadley b0e6436
Debugging
hadley 94f9fb7
Temporarily disable parallel testing
hadley cb34d73
Revert changes
hadley 4197157
Merge commit 'a7e7a3ead470381dc7625fc51a4c29d9cad229ed'
hadley 88dda10
Merge commit '952ca9ec6bd39671027d9a0431799021c9fabe60'
hadley f056117
Rename file
hadley 082dc3c
Restore accidental deletion
hadley File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or 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 |
|---|---|---|
|
|
@@ -6,7 +6,7 @@ | |
| "Bash(R:*)", | ||
| "Bash(rm:*)", | ||
| "Bash(air format:*)", | ||
| "Edit(/**)", | ||
| "Edit(**)" | ||
| ], | ||
| "deny": [] | ||
| } | ||
|
|
||
This file contains hidden or 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 hidden or 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 hidden or 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 hidden or 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,100 @@ | ||
| #' Claude web search tool | ||
| #' | ||
| #' @description | ||
| #' Enables Claude to search the web for up-to-date information. Your organization | ||
| #' administrator must enable web search in the Anthropic Console before using | ||
| #' this tool, as it costs extra ($10 per 1,000 tokens at time of writing). | ||
| #' | ||
| #' Learn more in <https://docs.claude.com/en/docs/agents-and-tools/tool-use/web-search-tool>. | ||
| #' | ||
| #' @param max_uses Integer. Maximum number of searches allowed per request. | ||
| #' @param allowed_domains Character vector. Restrict searches to specific domains | ||
| #' (e.g., `c("nytimes.com", "bbc.com")`). Cannot be used with `blocked_domains`. | ||
| #' @param blocked_domains Character vector. Exclude specific domains from searches. | ||
| #' Cannot be used with `allowed_domains`. | ||
| #' @param user_location List with optional elements: `country` (2-letter code), | ||
| #' `city`, `region`, and `timezone` (IANA timezone) to localize search results. | ||
| #' | ||
| #' @family built-in tools | ||
| #' @export | ||
| #' @examples | ||
| #' \dontrun{ | ||
| #' chat <- chat_claude() | ||
| #' chat$register_tool(claude_tool_web_search()) | ||
| #' chat$chat("What was in the news today?") | ||
| #' chat$chat("What's the biggest news in the economy?") | ||
| #' } | ||
| claude_tool_web_search <- function( | ||
| max_uses = NULL, | ||
| allowed_domains = NULL, | ||
| blocked_domains = NULL, | ||
| user_location = NULL | ||
| ) { | ||
| check_exclusive(allowed_domains, blocked_domains, .require = FALSE) | ||
|
|
||
| check_number_whole(max_uses, allow_null = TRUE, min = 1) | ||
| check_character(allowed_domains, allow_null = TRUE) | ||
| check_character(blocked_domains, allow_null = TRUE) | ||
|
|
||
| json <- compact(list( | ||
| name = "web_search", | ||
| type = "web_search_20250305", | ||
| max_uses = max_uses, | ||
| allowed_domains = allowed_domains, | ||
| blocked_domains = blocked_domains, | ||
| user_location = user_location | ||
| )) | ||
| ToolBuiltIn("web_search", json = json) | ||
| } | ||
|
|
||
| #' Claude web fetch tool | ||
| #' | ||
| #' @description | ||
| #' Enables Claude to fetch and analyze content from web URLs. Claude can only | ||
| #' fetch URLs that appear in the conversation context (user messages or | ||
| #' previous tool results). For security reasons, Claude cannot dynamically | ||
| #' construct URLs to fetch. | ||
| #' | ||
| #' Requires the `web-fetch-2025-09-10` beta header. | ||
| #' Learn more in <https://docs.claude.com/en/docs/agents-and-tools/tool-use/web-fetch-tool>. | ||
| #' | ||
| #' @param max_uses Integer. Maximum number of fetches allowed per request. | ||
| #' @param allowed_domains Character vector. Restrict fetches to specific domains. | ||
| #' Cannot be used with `blocked_domains`. | ||
| #' @param blocked_domains Character vector. Exclude specific domains from fetches. | ||
| #' Cannot be used with `allowed_domains`. | ||
| #' @param citations Logical. Whether to include citations in the response. Default is `TRUE`. | ||
| #' @param max_content_tokens Integer. Maximum number of tokens to fetch from each URL. | ||
| #' | ||
| #' @family built-in tools | ||
| #' @export | ||
| #' @examples | ||
| #' \dontrun{ | ||
| #' chat <- chat_claude(beta_headers = "web-fetch-2025-09-10") | ||
| #' chat$register_tool(claude_tool_web_fetch()) | ||
| #' chat$chat("What are the latest package releases on https://tidyverse.org/blog") | ||
| #' } | ||
| claude_tool_web_fetch <- function( | ||
| max_uses = NULL, | ||
| allowed_domains = NULL, | ||
| blocked_domains = NULL, | ||
| citations = FALSE, | ||
| max_content_tokens = NULL | ||
| ) { | ||
| check_exclusive(allowed_domains, blocked_domains, .require = FALSE) | ||
|
|
||
| check_character(allowed_domains, allow_null = TRUE) | ||
| check_character(blocked_domains, allow_null = TRUE) | ||
| check_bool(citations) | ||
|
|
||
| json <- compact(list( | ||
| name = "web_fetch", | ||
| type = "web_fetch_20250910", | ||
| max_uses = max_uses, | ||
| allowed_domains = allowed_domains, | ||
| blocked_domains = blocked_domains, | ||
| citations = list(enabled = citations), | ||
| max_content_tokens = max_content_tokens | ||
| )) | ||
| ToolBuiltIn("web_fetch", json) | ||
| } | ||
This file contains hidden or 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 hidden or 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,43 @@ | ||
| #' Google web search (grounding) tool | ||
| #' | ||
| #' @description | ||
| #' Enables Gemini models to search the web for up-to-date information and ground | ||
| #' responses with citations to sources. The model automatically decides when | ||
| #' (and how) to search the web based on your prompt. Search results are | ||
| #' incorporated into the response with grounding metadata including source | ||
| #' URLs and titles. | ||
| #' | ||
| #' Learn more in <https://ai.google.dev/gemini-api/docs/google-search>. | ||
| #' | ||
| #' @family built-in tools | ||
| #' @export | ||
| #' @examples | ||
| #' \dontrun{ | ||
| #' chat <- chat_google_gemini() | ||
| #' chat$register_tool(google_tool_web_search()) | ||
| #' chat$chat("What was in the news today?") | ||
| #' chat$chat("What's the biggest news in the economy?") | ||
| #' } | ||
| google_tool_web_search <- function() { | ||
| ToolBuiltIn("web_search", list(google_search = set_names(list()))) | ||
| } | ||
|
|
||
| #' Google URL fetch tool | ||
| #' | ||
| #' @description | ||
| #' When this tool is enabled, you can include URLs directly in your prompts and | ||
| #' Gemini will fetch and analyze the content. | ||
| #' | ||
| #' Learn more in <https://ai.google.dev/gemini-api/docs/url-context>. | ||
| #' | ||
| #' @family built-in tools | ||
| #' @export | ||
| #' @examples | ||
| #' \dontrun{ | ||
| #' chat <- chat_google_gemini() | ||
| #' chat$register_tool(google_tool_web_fetch()) | ||
| #' chat$chat("What are the latest package releases on https://tidyverse.org/blog?") | ||
| #' } | ||
| google_tool_web_fetch <- function() { | ||
| ToolBuiltIn(name = "web_fetch", json = list(url_context = set_names(list()))) | ||
| } |
This file contains hidden or 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 hidden or 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,49 @@ | ||
| #' OpenAI web search tool | ||
| #' | ||
| #' @description | ||
| #' Enables OpenAI models to search the web for up-to-date information. The search | ||
| #' behavior varies by model: non-reasoning models perform simple searches, while | ||
| #' reasoning models can perform agentic, iterative searches. | ||
| #' | ||
| #' Learn more at <https://platform.openai.com/docs/guides/tools-web-search> | ||
| #' | ||
| #' @param allowed_domains Character vector. Restrict searches to specific domains | ||
| #' (e.g., `c("nytimes.com", "bbc.com")`). Maximum 20 domains. URLs will be | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nytimes.com is a hilarious domain to suggest to use with OpenAI
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Claude suggested that 😆 |
||
| #' automatically cleaned (http/https prefixes removed). | ||
| #' @param user_location List with optional elements: `country` (2-letter ISO code), | ||
| #' `city`, `region`, and `timezone` (IANA timezone) to localize search results. | ||
| #' @param external_web_access Logical. Whether to allow live internet access | ||
| #' (`TRUE`, default) or use only cached/indexed results (`FALSE`). | ||
| #' | ||
| #' @family built-in tools | ||
| #' @export | ||
| #' @examples | ||
| #' \dontrun{ | ||
| #' chat <- chat_openai() | ||
| #' chat$register_tool(openai_tool_web_search()) | ||
| #' chat$chat("Very briefly summarise the top 3 news stories of the day") | ||
| #' chat$chat("Of those stories, which one do you think was the most interesting?") | ||
| #' } | ||
| openai_tool_web_search <- function( | ||
| allowed_domains = NULL, | ||
| user_location = NULL, | ||
| external_web_access = TRUE | ||
| ) { | ||
| check_character(allowed_domains, allow_null = TRUE) | ||
| check_bool(external_web_access) | ||
|
|
||
| # Strip http/https from domains | ||
| if (!is.null(allowed_domains)) { | ||
| allowed_domains <- sub("^https?://", "", allowed_domains) | ||
| } | ||
|
|
||
| json <- compact(list( | ||
| type = "web_search", | ||
| filters = if (!is.null(allowed_domains)) { | ||
| list(allowed_domains = allowed_domains) | ||
| }, | ||
| user_location = user_location, | ||
| external_web_access = external_web_access | ||
| )) | ||
| ToolBuiltIn("web_search", json) | ||
| } | ||
This file contains hidden or 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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is it that this isn't just set for the user?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just because it's a beta header; felt weird to me.