Follow Discord
Sweep 22 Oct 2026 · 21:04Z Build v2.1.309 528 read Stable v2.1.308 Latest v2.1.309 Next v2.1.309 Feeds RSS JSON llms.txt llms-full.txt Unofficial
One change · api

browser-use-tool changedagents-and-tools/tool-use/browser-use-tool

Nearest release: v2.1.309, published 3 hours before this site recorded the change. Shown because the two are within 24 hours of each other. Nothing here says the release caused the edit.

Recorded here
Lines+28added
Lines−20removed
From line 20 where the diff opens
First seen 20 Aug 2026 this site's first read of the page
Recorded edits23to this page, all time

The whole hunk

from line 20, old and new numbered
/
lines
from line 20
2020 - claude-haiku-5-5
2121 supportedPlatforms:
2222 Claude API: ga
23 Google Cloud: ga
23 Claude Models on Google Cloud (Google managed): ga
2424---
2525 
2626<Note>
from line 173
173173 messages: [
174174 ['role' => 'user', 'content' => 'Open example.com/docs and tell me how to get started.'],
175175 ],
176 model: 'claude-opus-5-5',
176 model: Model::CLAUDE_OPUS_5_5,
177177 tools: [
178178 ['type' => 'browser_toolset_20260801'],
179179 ],
from line 562
562562 
563563 ToolResultBlockParam.Content captureScreenshot() {
564564 ImageBlockParam image = ImageBlockParam.builder()
565 .source(Base64ImageSource.builder()
566 .mediaType(Base64ImageSource.MediaType.IMAGE_PNG)
567 .data(PLACEHOLDER_PNG)
568 .build())
569 .build();
565 .source(Base64ImageSource.builder()
566 .mediaType(Base64ImageSource.MediaType.IMAGE_PNG)
567 .data(PLACEHOLDER_PNG)
568 .build())
569 .build();
570570 return ToolResultBlockParam.Content.ofBlocks(
571 List.of(ToolResultBlockParam.Content.Block.ofImage(image)));
571 List.of(ToolResultBlockParam.Content.Block.ofImage(image)));
572572 }
573573 
574574 String navigate(String url) {
from line 577
577577 
578578 String readPage() {
579579 return """
580 link "Docs" [ref_1]
581 button "Search" [ref_2]""";
580 link "Docs" [ref_1]
581 button "Search" [ref_2]""";
582582 }
583583 
584584 String clickRef(String ref) {
from line 604
604604 case "left_click" -> {
605605 // target is {"type": "ref", "ref": "ref_1"} or {"type": "coordinate", "x": 640, "y": 380}
606606 Map<String, JsonValue> target =
607 (Map<String, JsonValue>) input.get("target").asObject().get();
607 (Map<String, JsonValue>) input.get("target").asObject().get();
608608 if (target.get("type").asStringOrThrow().equals("ref")) {
609609 yield clickRef(target.get("ref").asStringOrThrow());
610610 }
from line 901
901901 }
902902 
903903 // processToolCalls runs the browser actions in Claude's response in order and
904 // builds one tool_result per tool_use block. After the first failure it skips
904 // builds one tool_result for each tool_use block. After the first failure it skips
905905 // the rest: Claude planned them assuming the earlier actions succeeded.
906906 func processToolCalls(response *anthropic.Message) []anthropic.ContentBlockParamUnion {
907907 var toolResults []anthropic.ContentBlockParamUnion
from line 941
941941 /** Every result answering a browser toolset member echoes toolset_name. */
942942 ToolResultBlockParam.Builder browserResult(ToolUseBlock toolUse) {
943943 return ToolResultBlockParam.builder()
944 .toolUseId(toolUse.id())
945 .toolsetName("browser");
944 .toolUseId(toolUse.id())
945 .toolsetName("browser");
946946 }
947947 
948948 /**
949949 * Run the browser actions in Claude's response in order and build one
950 * tool_result per tool_use block. After the first failure, skip the rest:
950 * tool_result for each tool_use block. After the first failure, skip the rest:
951951 * Claude planned them assuming the earlier actions succeeded.
952952 */
953953 List<ContentBlockParam> processToolCalls(Message response) {
from line 961
961961 ToolUseBlock toolUse = block.asToolUse();
962962 ToolResultBlockParam result;
963963 if (failed) {
964 result = browserResult(toolUse).content(HALT_TEXT).isError(true).build();
964 result = browserResult(toolUse)
965 .content(HALT_TEXT)
966 .isError(true)
967 .build();
965968 } else {
966969 try {
967970 Map<String, JsonValue> input =
968 (Map<String, JsonValue>) toolUse._input().asObject().get();
971 (Map<String, JsonValue>) toolUse._input().asObject().get();
969972 ToolResultBlockParam.Content output = handleBrowserAction(toolUse.name(), input);
970973 // A real executor also adds a browser_state block to navigation and
971974 // tab-management results; see "Track tabs with browser_state" on this page.
972 result = browserResult(toolUse).content(output).build();
975 result = browserResult(toolUse)
976 .content(output)
977 .build();
973978 } catch (RuntimeException e) {
974979 failed = true;
975 result = browserResult(toolUse).content("Error: " + e.getMessage()).isError(true).build();
980 result = browserResult(toolUse)
981 .content("Error: " + e.getMessage())
982 .isError(true)
983 .build();
976984 }
977985 }
978986 toolResults.add(ContentBlockParam.ofToolResult(result));
from line 1024
10161024 NOT_EXECUTED = "Not executed: an earlier action in this turn failed."
10171025 
10181026 # Run the browser actions in Claude's response in order and build one
1019 # tool_result per tool_use block. After the first failure, skip the rest:
1027 # tool_result for each tool_use block. After the first failure, skip the rest:
10201028 # Claude planned them assuming the earlier actions succeeded.
10211029 def process_tool_calls(response)
10221030 tool_results = []
Feedback