From 87759a37661f3e2a3eb8002516e23d0666f94162 Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Fri, 5 Dec 2025 19:12:02 +0400 Subject: [PATCH 1/8] chore(internal): simplify http snapshots --- ...c6a7970758bac7d0487f9b1afaad2cc095f3c.json | 4 - CONTRIBUTING.md | 10 +- pyproject.toml | 1 + tests/conftest.py | 16 + .../48aac7c3-f271-47b3-854b-af4ed31e10bb.json | 3 - .../606342ef-f614-4bc1-b5e7-2c3305a48bf3.json | 22 + tests/lib/_parse/test_beta_messages.py | 21 +- tests/lib/snapshots.py | 259 --------- .../ab7b2edd-9c2d-4f53-9c04-92bb659b9caa.json | 4 - .../a0a711eb-ee0e-4a42-88d6-5c7f83c0f25a.txt | 1 - .../9cb114c8-69bd-4111-841b-edee30333afd.json | 4 - .../4a71c9f9-6191-4820-b1a1-89f3bb179078.json | 106 ++++ .../6401445a-5758-4777-9778-3008bae873ec.json | 93 ++++ .../6cd089e9-1c08-40a5-851d-c272b3f1c248.json | 149 +++++ .../6f763c87-ecb6-4217-8f6f-32db8e84a6be.json | 183 +++++++ .../ad005e89-f72b-4f0e-941a-9ec3473c1bc8.json | 93 ++++ .../e4c374b8-ae08-48f3-96e5-9d28066820b0.json | 96 ++++ .../f1c3350a-cdb1-4508-a208-18544b825a9e.json | 93 ++++ .../f27add0c-5771-4452-8ed9-996f5d74ef77.json | 42 ++ .../ff848716-2309-477f-8e90-39877809aaad.json | 42 ++ .../c4061e82-ea59-4756-9549-71a35da24499.json | 93 ++++ .../9cb114c8-69bd-4111-841b-edee30333afd.json | 4 - tests/lib/tools/test_runners.py | 509 ++++++++++-------- tests/lib/utils.py | 31 +- uv.lock | 21 +- 25 files changed, 1365 insertions(+), 535 deletions(-) delete mode 100644 .inline-snapshot/external/cd8d3d185e7a993935ab650e0e5c6a7970758bac7d0487f9b1afaad2cc095f3c.json delete mode 100644 tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages.test_stream_with_raw_schema/48aac7c3-f271-47b3-854b-af4ed31e10bb.json create mode 100644 tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages/606342ef-f614-4bc1-b5e7-2c3305a48bf3.json delete mode 100644 tests/lib/snapshots.py delete mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_compaction_control/ab7b2edd-9c2d-4f53-9c04-92bb659b9caa.json delete mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_server_side_tool/a0a711eb-ee0e-4a42-88d6-5c7f83c0f25a.txt delete mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_streaming_call_sync_events/9cb114c8-69bd-4111-841b-edee30333afd.json create mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/4a71c9f9-6191-4820-b1a1-89f3bb179078.json create mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6401445a-5758-4777-9778-3008bae873ec.json create mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6cd089e9-1c08-40a5-851d-c272b3f1c248.json create mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6f763c87-ecb6-4217-8f6f-32db8e84a6be.json create mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ad005e89-f72b-4f0e-941a-9ec3473c1bc8.json create mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/e4c374b8-ae08-48f3-96e5-9d28066820b0.json create mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f1c3350a-cdb1-4508-a208-18544b825a9e.json create mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f27add0c-5771-4452-8ed9-996f5d74ef77.json create mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ff848716-2309-477f-8e90-39877809aaad.json create mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/__module__/c4061e82-ea59-4756-9549-71a35da24499.json delete mode 100644 tests/lib/tools/__inline_snapshot__/test_runners/test_streaming_call_sync_events/9cb114c8-69bd-4111-841b-edee30333afd.json diff --git a/.inline-snapshot/external/cd8d3d185e7a993935ab650e0e5c6a7970758bac7d0487f9b1afaad2cc095f3c.json b/.inline-snapshot/external/cd8d3d185e7a993935ab650e0e5c6a7970758bac7d0487f9b1afaad2cc095f3c.json deleted file mode 100644 index 1de1d9f3..00000000 --- a/.inline-snapshot/external/cd8d3d185e7a993935ab650e0e5c6a7970758bac7d0487f9b1afaad2cc095f3c.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_01C63EzoQa1oa1eNn778a6ep\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":3,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll get\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" the weather for San Francisco for you.\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_011V184uLZKFsxYfCJSjiQ6q\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"loc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ati\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"on\\\": \\\"San Fr\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"anc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"isc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"o, CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"units\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \\\"f\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":85} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_01Vm8Ddgc8qm4iuUSKbf6jku\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":781,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":6,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The weather in San Francisco,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" CA is currently **Sunny** with a temperature of **\"}}\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"68°F**.\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":781,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":25} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" -] \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1fd93e01..84871033 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -99,7 +99,6 @@ $ ./scripts/test ### Snapshots Some tests use [inline-snapshot](https://15r10nk.github.io/inline-snapshot/latest/). To update them after making changes, rerun the tests with the `--inline-snapshot=fix` and `-n0` options: - ```bash ./scripts/test --inline-snapshot=fix -n0 ``` @@ -108,15 +107,14 @@ Some tests use [inline-snapshot](https://15r10nk.github.io/inline-snapshot/lates > `inline-snapshot` is incompatible with [pytest-xdist](https://github.com/pytest-dev/pytest-xdist), so you need to disable parallel execution `(-n0)` when using the `--inline-snapshot` option. In addition, some tests capture snapshots of the HTTP requests they make. -To refresh these snapshots, run the tests with the `ANTHROPIC_LIVE=1` environment variable enabled. - +To refresh these snapshots, run the tests with the `--http-record` flag: ```bash -ANTHROPIC_LIVE=1 ./scripts/test --inline-snapshot=fix +./scripts/test --inline-snapshot=fix --http-record ``` > [!NOTE] -> Sometimes it makes sense to update only the inline snapshots `(--inline-snapshot=fix)` without refreshing the HTTP snapshots `(ANTHROPIC_LIVE=1)`. -> This is useful when the endpoint hasn’t changed, but your code handles the response differently and the assertions need updating. +> Sometimes it makes sense to update only the inline snapshots `(--inline-snapshot=fix)` without refreshing the HTTP snapshots `(--http-record)`. +> This is useful when the endpoint hasn't changed, but your code handles the response differently and the assertions need updating. ## Linting and formatting diff --git a/pyproject.toml b/pyproject.toml index 31186601..bfe7fdf4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,6 +74,7 @@ dev = [ "pytest-xdist>=3.6.1", "inline-snapshot>=0.28.0", "griffe>=1", + "http-snapshot[httpx]==0.1.4", ] pydantic-v1 = [ "pydantic>=1.9.0,<2", diff --git a/tests/conftest.py b/tests/conftest.py index b1ac2570..62f0c002 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -58,6 +58,22 @@ def client(request: FixtureRequest) -> Iterator[Anthropic]: yield client +@pytest.fixture(scope="function") +def snapshot_client(snapshot_sync_httpx_client: httpx.Client, is_recording: bool) -> Iterator[Anthropic]: + with Anthropic(http_client=snapshot_sync_httpx_client, api_key=None if is_recording else api_key) as client: + yield client + + +@pytest.fixture(scope="function") +async def async_snapshot_client( + snapshot_async_httpx_client: httpx.AsyncClient, is_recording: bool +) -> AsyncIterator[AsyncAnthropic]: + async with AsyncAnthropic( + http_client=snapshot_async_httpx_client, api_key=None if is_recording else api_key + ) as client: + yield client + + @pytest.fixture(scope="session") async def async_client(request: FixtureRequest) -> AsyncIterator[AsyncAnthropic]: param = getattr(request, "param", True) diff --git a/tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages.test_stream_with_raw_schema/48aac7c3-f271-47b3-854b-af4ed31e10bb.json b/tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages.test_stream_with_raw_schema/48aac7c3-f271-47b3-854b-af4ed31e10bb.json deleted file mode 100644 index bb41bc2b..00000000 --- a/tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages.test_stream_with_raw_schema/48aac7c3-f271-47b3-854b-af4ed31e10bb.json +++ /dev/null @@ -1,3 +0,0 @@ -[ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01EZum6x6zixptqit3SdTzgt\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":135,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"[\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"12\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"345,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"67890]\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":135,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":10}}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" -] \ No newline at end of file diff --git a/tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages/606342ef-f614-4bc1-b5e7-2c3305a48bf3.json b/tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages/606342ef-f614-4bc1-b5e7-2c3305a48bf3.json new file mode 100644 index 00000000..ea5ddbb6 --- /dev/null +++ b/tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages/606342ef-f614-4bc1-b5e7-2c3305a48bf3.json @@ -0,0 +1,22 @@ +[ + { + "response": { + "status_code": 200, + "headers": { + "date": "Fri, 05 Dec 2025 15:06:08 GMT", + "content-type": "text/event-stream; charset=utf-8", + "connection": "keep-alive", + "cf-ray": "9a947204ac019fb2-AMS", + "cache-control": "no-cache", + "request-id": "req_011CVokJu9sXWCZuA7nVS1g3", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "3888", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare" + }, + "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_015jm362jgYXWyFRvq8NHxPr\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":135,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"[\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"12\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"345,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"67890]\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":135,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":10} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" + } + } +] \ No newline at end of file diff --git a/tests/lib/_parse/test_beta_messages.py b/tests/lib/_parse/test_beta_messages.py index b869f018..ccfd8c4d 100644 --- a/tests/lib/_parse/test_beta_messages.py +++ b/tests/lib/_parse/test_beta_messages.py @@ -1,16 +1,21 @@ +from typing import Any, cast + import pytest -from respx import MockRouter from inline_snapshot import external, snapshot from anthropic import AsyncAnthropic, _compat from anthropic.types.beta.parsed_beta_message import ParsedBetaMessage -from ..snapshots import make_async_stream_snapshot_request - @pytest.mark.skipif(_compat.PYDANTIC_V1, reason="tool runner not supported with pydantic v1") class TestAsyncMessages: - async def test_stream_with_raw_schema(self, async_client: AsyncAnthropic, respx_mock: MockRouter) -> None: + @pytest.mark.parametrize( + "http_snapshot", + [ + cast(Any, external("uuid:606342ef-f614-4bc1-b5e7-2c3305a48bf3.json")), + ], + ) + async def test_stream_with_raw_schema(self, async_snapshot_client: AsyncAnthropic) -> None: async def async_stream_parse(client: AsyncAnthropic) -> ParsedBetaMessage[None]: async with client.beta.messages.stream( model="claude-sonnet-4-5", @@ -32,12 +37,6 @@ async def async_stream_parse(client: AsyncAnthropic) -> ParsedBetaMessage[None]: ) as stream: return await stream.get_final_message() - response = await make_async_stream_snapshot_request( - async_stream_parse, - content_snapshot=external("uuid:48aac7c3-f271-47b3-854b-af4ed31e10bb.json"), - respx_mock=respx_mock, - mock_client=async_client, - path="/v1/messages?beta=true", - ) + response = await async_stream_parse(async_snapshot_client) assert response.content[0].text == snapshot("[12345,67890]") diff --git a/tests/lib/snapshots.py b/tests/lib/snapshots.py deleted file mode 100644 index 5ca46365..00000000 --- a/tests/lib/snapshots.py +++ /dev/null @@ -1,259 +0,0 @@ -from __future__ import annotations - -import os -import json -from typing import Any, List, Callable, Awaitable, cast -from typing_extensions import TypeVar - -import httpx -from respx import MockRouter -from inline_snapshot import outsource, get_snapshot_value - -from anthropic import Anthropic, AsyncAnthropic -from anthropic._utils._utils import is_list - -_T = TypeVar("_T") - - -def make_snapshot_request( - func: Callable[[Anthropic], _T], - *, - content_snapshot: Any, - respx_mock: MockRouter, - mock_client: Anthropic, - path: str, -) -> _T: - live = os.environ.get("ANTHROPIC_LIVE") == "1" - collected: list[str] = [] - if live: - - def _on_response(response: httpx.Response) -> None: - collected.append(json.dumps(json.loads(response.read()))) - - respx_mock.stop() - - client = Anthropic( - http_client=httpx.Client( - event_hooks={ - "response": [_on_response], - } - ) - ) - else: - responses = get_snapshot_value(content_snapshot) - - if not is_list(responses): - responses = [responses] - - curr = 0 - - def get_response(_request: httpx.Request) -> httpx.Response: - nonlocal curr - content = responses[curr] - assert isinstance(content, str) - - curr += 1 - return httpx.Response( - 200, - content=content, - headers={"content-type": "application/json"}, - ) - - respx_mock.post(path).mock(side_effect=get_response) - - client = mock_client - - result = func(client) - - if not live: - return result - - client.close() - - if len(collected) == 1: - assert collected[0] == content_snapshot - else: - assert collected == content_snapshot - - return result - - -def make_stream_snapshot_request( - func: Callable[[Anthropic], _T], - *, - content_snapshot: Any, - respx_mock: MockRouter, - mock_client: Anthropic, - path: str, -) -> _T: - live = os.environ.get("ANTHROPIC_LIVE") == "1" - collected: list[str] = [] - if live: - - def _on_response(response: httpx.Response) -> None: - response.read() - collected.append(response.text) - - respx_mock.stop() - - client = Anthropic( - http_client=httpx.Client( - event_hooks={ - "response": [_on_response], - } - ) - ) - else: - response_contents = get_snapshot_value(content_snapshot) - assert is_list(response_contents) - - response_contents = cast( - List[str], - response_contents, - ) - - curr = 0 - - def get_response(_request: httpx.Request) -> httpx.Response: - nonlocal curr - content = response_contents[curr] - assert isinstance(content, str) - - curr += 1 - return httpx.Response( - 200, - content=content.encode("utf-8"), - headers={"content-type": "text/event-stream"}, - ) - - respx_mock.post(path).mock(side_effect=get_response) - client = mock_client - - result = func(client) - if not live: - return result - - assert outsource(collected) == content_snapshot - return result - - -async def make_async_stream_snapshot_request( - func: Callable[[AsyncAnthropic], Awaitable[_T]], - *, - content_snapshot: Any, - respx_mock: MockRouter, - mock_client: AsyncAnthropic, - path: str, -) -> _T: - live = os.environ.get("ANTHROPIC_LIVE") == "1" - collected: list[str] = [] - if live: - - async def _on_response(response: httpx.Response) -> None: - await response.aread() - collected.append(response.text) - - respx_mock.stop() - - client = AsyncAnthropic( - http_client=httpx.AsyncClient( - event_hooks={ - "response": [_on_response], - } - ) - ) - else: - response_contents = get_snapshot_value(content_snapshot) - assert is_list(response_contents) - - response_contents = cast( - List[str], - response_contents, - ) - - curr = 0 - - def get_response(_request: httpx.Request) -> httpx.Response: - nonlocal curr - content = response_contents[curr] - assert isinstance(content, str) - - curr += 1 - return httpx.Response( - 200, - content=content.encode("utf-8"), - headers={"content-type": "text/event-stream"}, - ) - - respx_mock.post(path).mock(side_effect=get_response) - client = mock_client - - result = await func(client) - if not live: - return result - - assert outsource(collected) == content_snapshot - return result - - -async def make_async_snapshot_request( - func: Callable[[AsyncAnthropic], Awaitable[_T]], - *, - content_snapshot: Any, - respx_mock: MockRouter, - mock_client: AsyncAnthropic, - path: str, -) -> _T: - live = os.environ.get("ANTHROPIC_LIVE") == "1" - collected: list[str] = [] - if live: - - async def _on_response(response: httpx.Response) -> None: - collected.append(json.dumps(json.loads(await response.aread()))) - - respx_mock.stop() - - client = AsyncAnthropic( - http_client=httpx.AsyncClient( - event_hooks={ - "response": [_on_response], - } - ) - ) - else: - responses = get_snapshot_value(content_snapshot) - - if not is_list(responses): - responses = [responses] - - curr = 0 - - def get_response(_request: httpx.Request) -> httpx.Response: - nonlocal curr - content = responses[curr] - assert isinstance(content, str) - - curr += 1 - return httpx.Response( - 200, - content=content, - headers={"content-type": "application/json"}, - ) - - respx_mock.post(path).mock(side_effect=get_response) - - client = mock_client - - result = await func(client) - - if not live: - return result - - await client.close() - - if len(collected) == 1: - assert collected[0] == content_snapshot - else: - assert collected == content_snapshot - - return result diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_compaction_control/ab7b2edd-9c2d-4f53-9c04-92bb659b9caa.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_compaction_control/ab7b2edd-9c2d-4f53-9c04-92bb659b9caa.json deleted file mode 100644 index aee71e4d..00000000 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_compaction_control/ab7b2edd-9c2d-4f53-9c04-92bb659b9caa.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - "{\"model\": \"claude-sonnet-4-5-20250929\", \"id\": \"msg_0191gBaqZk5tPXrUvt9e6iaU\", \"type\": \"message\", \"role\": \"assistant\", \"content\": [{\"type\": \"text\", \"text\": \"I'll write a detailed 500-word essay about dogs, cats, and birds for you.\\n\\n---\\n\\n**Our Beloved Companions: Dogs, Cats, and Birds**\\n\\nThroughout human history, animals have played an integral role in our lives, providing companionship, entertainment, and emotional support. Among the most popular pets worldwide are dogs, cats, and birds, each offering unique characteristics and forming special bonds with their human caretakers.\\n\\n**Dogs: Loyal Friends and Protectors**\\n\\nDogs have earned their reputation as \\\"man's best friend\\\" through thousands of years of domestication and companionship. These remarkable animals are known for their unwavering loyalty, intelligence, and adaptability. From tiny Chihuahuas to massive Great Danes, dogs come in an astounding variety of breeds, each developed for specific purposes ranging from herding and hunting to companionship and service work.\\n\\nWhat makes dogs particularly special is their ability to form deep emotional connections with humans. They can read human emotions, respond to training, and provide comfort during difficult times. Dogs require regular exercise, social interaction, and mental stimulation to thrive. Their playful nature and enthusiasm for life can brighten even the darkest days. Many dogs serve in specialized roles as service animals, therapy dogs, search and rescue workers, and police partners, demonstrating their versatility and intelligence.\\n\\n**Cats: Independent and Enigmatic**\\n\\nCats offer a different kind of companionship, characterized by independence and mysterious charm. These graceful felines have been associated with humans for thousands of years, originally valued for their prowess in controlling rodent populations. Today, cats are beloved for their low-maintenance care requirements and affectionate, albeit selective, nature.\\n\\nUnlike dogs, cats are generally more self-sufficient and require less direct attention, making them ideal for busy households or individuals with limited space. They are naturally clean animals, spending hours grooming themselves and instinctively using litter boxes. Cats communicate through various vocalizations, body language, and purring\\u2014a soothing sound that has been shown to have therapeutic effects on human health. Their playful hunting instincts emerge during play sessions, and their quiet companionship provides comfort without the demanding neediness sometimes associated with other pets.\\n\\n**Birds: Colorful and Vocal Companions**\\n\\nBirds bring vibrant colors, melodious songs, and surprising intelligence into homes around the world. From small budgerigars to large parrots, pet birds offer unique interactive experiences. Many bird species are highly intelligent, capable of learning tricks, mimicking speech, and solving puzzles. Their cognitive abilities often surprise those unfamiliar with avian pets.\\n\\nBirds are social creatures that thrive on interaction, both with their human caretakers and, ideally, with other birds. They require specialized care, including proper nutrition, spacious cages, toys for mental stimulation, and regular veterinary checkups. Their beautiful plumage and cheerful songs can transform a home's atmosphere, providing natural entertainment and beauty. Some species, particularly parrots, can live for decades, forming lifelong bonds with their owners.\\n\\n**Conclusion**\\n\\nDogs, cats, and birds each offer distinct advantages as companions, and the choice between them often depends on lifestyle, living situation, and personal preferences. Dogs provide active companionship and loyalty, cats offer independent affection and ease of care, and birds bring beauty and intelligence in compact packages. Regardless of which animal someone chooses, the bond between humans and their pets enriches lives immeasurably, teaching us about responsibility, empathy, and unconditional love.\\n\\n---\"}, {\"type\": \"tool_use\", \"id\": \"toolu_0147W1ET6XbT4dqWtoCugLgd\", \"name\": \"submit_analysis\", \"input\": {\"summary\": \"This comprehensive 500-word essay explores three popular companion animals: dogs, cats, and birds. Dogs are presented as loyal, intelligent, and versatile companions known for their emotional bonds with humans and their roles in service work. They require regular exercise and social interaction, coming in diverse breeds suited for various purposes. Cats are described as independent, low-maintenance pets that offer selective affection and therapeutic benefits through their purring and calm presence. They are naturally clean and ideal for busy households. Birds are highlighted for their vibrant colors, intelligence, and ability to mimic speech and learn tricks. They require specialized care and social interaction, with some species living for decades. The essay concludes that each animal offers unique benefits suited to different lifestyles, and all provide valuable companionship that enriches human lives through responsibility, empathy, and unconditional love.\"}}], \"stop_reason\": \"tool_use\", \"stop_sequence\": null, \"usage\": {\"input_tokens\": 617, \"cache_creation_input_tokens\": 0, \"cache_read_input_tokens\": 0, \"cache_creation\": {\"ephemeral_5m_input_tokens\": 0, \"ephemeral_1h_input_tokens\": 0}, \"output_tokens\": 998, \"service_tier\": \"standard\"}}", - "{\"model\": \"claude-sonnet-4-5-20250929\", \"id\": \"msg_01KkGypgLRVfvx2SP81PMKYy\", \"type\": \"message\", \"role\": \"assistant\", \"content\": [{\"type\": \"text\", \"text\": \"\\n## 1. Task Overview\\nThe user requests a 500-word essay about dogs, cats, and birds, followed by a single call to the `submit_analysis` tool at the end containing information about all three animals. \\n\\n**Key constraints:**\\n- Essay must be detailed and approximately 500 words\\n- Must cover all three animals: dogs, cats, and birds\\n- Tool `submit_analysis` must be called exactly once, at the end\\n- Tool call should contain information about all three animals\\n\\n## 2. Current State\\n**Completed:** Nothing has been completed yet.\\n\\n**Status:** The task has been acknowledged but no essay has been written and no tool has been called.\\n\\n**Artifacts produced:** None yet.\\n\\n## 3. Important Discoveries\\n**Technical requirements:**\\n- Need to understand the parameters/schema for `submit_analysis` tool (not yet verified)\\n- Must structure the tool call to include data about all three animal types in a single invocation\\n\\n**Approach to take:**\\n- Write a comprehensive 500-word essay discussing dogs, cats, and birds\\n- Essay should cover characteristics, behaviors, and comparisons between the three\\n- Extract/organize key information about each animal for the tool call\\n- Call `submit_analysis` once with consolidated data about all three animals\\n\\n## 4. Next Steps\\n1. **Write the 500-word essay** covering:\\n - Dogs: characteristics, behavior, relationship with humans\\n - Cats: characteristics, behavior, relationship with humans\\n - Birds: characteristics, behavior, diversity\\n - Comparisons and contrasts between the three\\n \\n2. **Determine the schema for `submit_analysis` tool** - check what parameters it accepts and how to structure data about multiple animals\\n\\n3. **Call `submit_analysis` once** with information about all three animals in the appropriate format\\n\\n4. **Verify word count** is approximately 500 words\\n\\n## 5. Context to Preserve\\n- User emphasized calling the tool \\\"only once at the end\\\"\\n- Essay should be \\\"detailed\\\" - not superficial\\n- The tool call must encompass information about all three animals, not separate calls per animal\\n- This appears to be a test of following multi-step instructions precisely\\n\"}], \"stop_reason\": \"end_turn\", \"stop_sequence\": null, \"usage\": {\"input_tokens\": 324, \"cache_creation_input_tokens\": 0, \"cache_read_input_tokens\": 0, \"cache_creation\": {\"ephemeral_5m_input_tokens\": 0, \"ephemeral_1h_input_tokens\": 0}, \"output_tokens\": 496, \"service_tier\": \"standard\"}}" -] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_server_side_tool/a0a711eb-ee0e-4a42-88d6-5c7f83c0f25a.txt b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_server_side_tool/a0a711eb-ee0e-4a42-88d6-5c7f83c0f25a.txt deleted file mode 100644 index ee9bf495..00000000 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_server_side_tool/a0a711eb-ee0e-4a42-88d6-5c7f83c0f25a.txt +++ /dev/null @@ -1 +0,0 @@ -{"model": "claude-haiku-4-5-20251001", "id": "msg_01NPxpnUAguLtyGiU3MzGnJD", "type": "message", "role": "assistant", "content": [{"type": "server_tool_use", "id": "srvtoolu_01RmcvokSHdbn2mkwmyHKURE", "name": "web_search", "input": {"query": "weather SF San Francisco today"}}, {"type": "web_search_tool_result", "tool_use_id": "srvtoolu_01RmcvokSHdbn2mkwmyHKURE", "content": [{"type": "web_search_result", "title": "San Francisco, CA Current Weather | AccuWeather", "url": "https://www.accuweather.com/en/us/san-francisco/94103/current-weather/347629", "encrypted_content": "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", "page_age": null}, {"type": "web_search_result", "title": "San Francisco Bay Area, CA", "url": "https://www.weather.gov/mtr/", "encrypted_content": "EtQCCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDJYwe5sfziwkyg0rlBoMsyPrfCA3WBM37U11IjBJaJ1zUVqikbCNdCe7DTLqbp8scvbE7awCz2dDVoc3W90ziM8ahDWC1d/ZYRK2Yn8q1wFdQ4OLZRe6Xogb3rIyZpC6izgCBZkadz2alIhT1I2jSROB3VlfXwqfO2MAT0tStI0X/ApUjGyafe/icIw/3AtdTviqKEQwmrZ9MVMH0syYaz4RIyn/7ORNw5FcN50JUpPNHVjNAcXbtq91MIjlqGAaLu17jYZy+K9Qj6Xm1A3panidk1/tlcjoDKNoZxPiwB48uwkEWKfaJ6ZtHPG9fbFkSvI64sItzevo9l1W87whIcSpEvWyykWxULOFoDzg2CsD+HvDomfZMpXvwTV7AQyXcLM6cuPLphgD", "page_age": null}, {"type": "web_search_result", "title": "San Francisco, CA Weather Forecast | AccuWeather", "url": "https://www.accuweather.com/en/us/san-francisco/94103/weather-forecast/347629", "encrypted_content": "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", "page_age": null}, {"type": "web_search_result", "title": "San Francisco, CA Weather Conditions | Weather Underground", "url": "https://www.wunderground.com/weather/us/ca/san-francisco", "encrypted_content": "Et8FCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDN3O1GnCiRxUE3IXwBoMlZbhTkEMpw7d2XnoIjCzSr5J1SLl3FjUTPQqXJ3GUurwJWssdKuBKrA8QlPv+bd8ErPF+6X/y2pd9p4P6gwq4gTSIwlvGVK63FUxZcEi3GK/iOCA0yBrJErLS9+1yoszLWoe1zkl3gAW0A2uqfuOLaU1vOUdhGqpIFtyTIx1/oG9/p9lGjZF9VrAMmMHkzRTVWCdfagDUgoGQDgEAvLI9Y4NJ0nuB9GnFhPNdpiKq3C7LtAd/+6i6jm/5Zl7b2R5kVSAXTWOzHmGhn14eBKNV++o6XkLOVF/2MkgwrrBbRMj2U07PJUElpoa1+qfRNNlKWILTAZGoJcYy7BH0eOPIUofozxYvn41LioaV4G4dwIPXOV0wTlzKOfG6MRBgj1Z4xk0fJae7mgIuuSF4pYnxD0T5tOZx8l3LsMm8685NMnDrKU98tK5Y/7uYXhDOnY78CAyHRACFS1CFLssLrb4wd8VbFTaLNSwuqz4nElo39HkHU/X7yFRv0vkMSSB6riM05P2h5jutaqCXJxT0poOJQRfS3Te3U3RaZkUjZAvzzSrh4xHHJAAJTf5vzhtysZPP7/pKyysoLbZQ1tzCKv7YrGaqHJcLO55FpVYQyVAQQ8FDCV4mRJOiyykyqXXSDid4InFaPg3d8sfZxu8alTIpuT7OGOzbB0DtlCUZ/mXaUNYzxF+IFeFLpHC7b0W4eYxIBnHLOfasLvxH5bzD0lRPlnQ0/hb1o9j7yLsKVvZtY3ezDBigOFAF/sTiIRpCLAk/BpU/oDsyN5bOHAHBzDUXQ02XwiPPE6/upDl3ATe/sU2aKDIKlxWtRZ9I2Z2eqp0VF029a06XkcVxkiMq2Bgzi0g/5JkYQUMW3mpWCc241ol2A6d4fOc3j9ckur4x7aVeee3GAM=", "page_age": null}, {"type": "web_search_result", "title": "San Francisco, CA Hourly Weather Forecast | Weather Underground", "url": "https://www.wunderground.com/hourly/us/ca/san-francisco", "encrypted_content": "EpAHCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDATwpbSmV8+sgnKr9hoMA5IWzAVP54d4q0L/IjDd6qCe5KwgF1xZKlTVFuxtv+Cjj4/wJ7XGpe+gngDcJieB8mY/lDjoYHos5WwwpQIqkwbUA24lSwTudHZWE19XGCsudsjLjCPI+tjVovlclpL3ayUz1dufuv54x+DxYbSaJpYmbKtWBek/36sriP2dgO03vPpVnayDZ/ggbr8B7hFmaUwj2NRGbJF/5OybMznE5AKeWnszWYr/5MTnY5sWqQiJpXGwJ96pv3BBD+x4egcvgimkXoRPE1RJNOlk/VIlu2qUJtq4w0HaQcNGKJdF5QLUJiWebHrBW5PNzUpydmU7nxeWdGSowv6Njdsk7uP4i5rFbjgZ4/WSoxA4ou+EMrAMvQUEIGiZf1jrTyhEH+hcZBEZsiGzswzsnTxNPkkc+mj2nhY1yDHDGeN0OYO2KpnjsZ0TGL02wY+HM6jFhLixHUFqyZf6svqL0wCW7CFCBQwaHNYRsY+FAho6HedFlDq4P4t9DyxPABoF1PSh0jRBsVueo2dY3nSAqHeN/VlxpBOG4BWif9FFxjjgvrAyaaQeRznzDcropAD2fbX6SKzvuVFtSGMQDGWCY5M6LCq0YGbygPbNyO5Uv2MgEDc57iJcfOAB6BT3MU9QrDszrwpP4HjD+N0j+UPo1wSvoYzizjyubLbKLEZcoDcLqo76pTOIkizGWvXK67yCzE288H11ltO4+nN1t46+sp6ZUXHTYDKNLjOt2hrj2V78oj1LKuWXokBUSt99ybzhhbQt6q6ocVQG2lcD3lo4JnQmH0+gqQ2fW4bcEAfsIGFFkfTxlN/Mo+1O1koFgTXFD7xubAruKivKHYQ2oFc7UVR2fyrSGX7zsM06XxcKJz9t+SDIUHb411zHZkfegBPI6RjyUf5GwvvKGSIQKA5BInCTOLiP+2kANXPE6t6Z/d1pp7pWLWB7RYEvibjrMmO7KQnfW+g9Q66hWw06rneFeDXVhNkhogcHp/IlsRwC5IcX8nCpmvO0e3qp3AKtJ9by6WP9izb3pkjj1RsO2N6CoguFVI1C6kucFi/fwP4Yo1fLjEIjCyKgoSOjsF/M4sk5CAIfyeJiuDs6sGPR1JElxrHB9mwFhJE9JXcbjqDy8vEKfligmEKzE2jEGAM=", "page_age": null}, {"type": "web_search_result", "title": "Zone Area Forecast for San Francisco County", "url": "https://forecast.weather.gov/MapClick.php?zoneid=CAZ006", "encrypted_content": "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", "page_age": null}, {"type": "web_search_result", "title": "Weather for San Francisco, California, USA", "url": "https://www.timeanddate.com/weather/usa/san-francisco", "encrypted_content": "EoIHCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDJUhfUPWe6QCEqL6xhoMQu+PGTxtAKXxWeVBIjBzTHEvlxvwu384Pc10vZXJ8SSMeO1x97ILnAPgv+/iBdi0DbFKt7WIHgqvKb6QmrwqhQaW7lDCJmyBgQaGPXZFZWQHLegTp2d4AIvzKY3r7QB3GX7gea/vBDUe0C1AitoIAO5Ac4Iz43kfw3F7ZT44VSXRMPO0OjuQEPb7fgqGwBZrNruJrooHThqqOYRFGN5ZqEIMN31M7r9qD4Kuf7+HzDABijJtbsHJp4BzJ3/ATMVwXSJPgdZIb/P/P2TXa6qj7TkiudP8052alm9yoZX9U9uAUA1MmHHXCQrF8iJ7oAWo9akuSgyAeE1BDniiTZe+BWLCTrsTV+QZo6PE+HZG2oGxo+UodFy1GRnXyTL1qFH108u8iyGqSdJh82OqqP2yHX5oDnHApYiQ2KMWj90K827q9QTzY7v+0A9LYTPWPPLZ9WHDnwdzsmfLynWzc6+eCIkfjHep0Xzr1QFoSAuoCjpEC8LVapurNAFYGOz1DRzKk2bQDW3ZZQlHpukUroetTALAwDbJ64KRxRefB+flaoTFN+XAqwt6gkMF97o+pcD7htqzU/PnjZUIXs32VlDQVv6AUG2j4mMDRiXSLuvSEqN0y17ySG2xjC3TBKxfQA82mE3FFY0edGIf+vzjGLSFrpxQ3e/u4WkeB7gsCcFq4cziReI4QjEjsniDmsQIXxHT5jJBVAkFUDQFHXYcbz+VrZeMu80t8qRxIpQbb0h4HlRGGNiv5sLwRdljhchQZaYH7lSNpw+V4ngfVrPJxFXOdXL7O1dVGtzbBxD6air20pgPMQy028C2w8AQXd0jyCFDW1+1r44/zvKsdbmbCFDv8bpqKC0XkbZ7M3/an9uQgnZLVbojr15V5jHPjQqggGJoRoNzJMWdfsA/dqBII7Dh2a4v2AM1Hvu5jOxoJbF9xZJfvUtfEhmjoJdtFJotJUDta8q8OvdQ9fMXaUVnC0e/FmzjoahnpYq74CDDPMEMZkT13yLBqF3yNlgE9uWqKpXAO1BuwzEn9t00CO6BYKufV8vqGa5NLNYVD+baD+8FuT1UIprk1si3O85WoPENJKXtYuggTMBJcLEE/3QeNPZOOPQ11/DXRRgD", "page_age": null}, {"type": "web_search_result", "title": "National Weather Service", "url": "https://forecast.weather.gov/MapClick.php?lat=37.7771&lon=-122.4196", "encrypted_content": "ErgBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDPdNpG1oXmpSBoMBNhoMj9hx750OkXsKskdBIjDwrSWsEjExCoOY6Z0/HBKNVZMHH0p/66s1UMdbMbQ3BpcnmdP/LRUQIYLlrj3imgYqPNowYxz7bhOflT7x7YRpg5cB99HVUBYRQYb4f3IpLc5aJvrzOImIq1jsQQqPMcQnnzm6s4v50JT2QwlwnhgD", "page_age": null}, {"type": "web_search_result", "title": "Weather", "url": "https://www.sfchronicle.com/weather/", "encrypted_content": "Eu0CCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDF7furbUQx58vewo3RoMYqiukXR+D6Z8NF+PIjBq9jLlRjra9mYzTHw3eJ7So3MoUbWmbxm74LLukofZuHdxDgFkNOp9PlTtLRW9RGkq8AExzlBbE/0xY+Ey+PS35i0spdIWxLPAL+M9/c9XVil+aeBv45XKZuUGzQZRZr6tkQ9yXcT5K7DvkjiPAKqnyTB9cMgpJ/FRwwgAgCyb2dGZp8RGaO5RkVQ1aohvGQozOO/KqIES/zwp2H+ZoF9f2K35A7y1ygAZfRIPZDINA2pkpc7EiQdeEmZYrMSmg60VoBkdbevq31aptfsLrQWlgMhuY92ipnOz5Gb+hV3m4nAUKdkCSpbfLjKhCJa47ZfV4dARcoxoy3mbkCk/0juVY+7g9me0uft1r1EOfiFx0WEntTPv/AfU81MAYNaWM3gRmzUYAw==", "page_age": null}, {"type": "web_search_result", "title": "Live Doppler 7 | Bay Area Weather News - ABC7 San Francisco", "url": "https://abc7news.com/weather/", "encrypted_content": "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", "page_age": null}]}, {"citations": [{"type": "web_search_result_location", "cited_text": "Home Weather USA San Francisco \u00b7 Now \u00b7 54 \u00b0F \u00b7 Fog. Feels Like: 52 \u00b0F Forecast: 62 / 49 \u00b0F Wind: 7 mph \u2191 from Northeast \u00b7 See more hour-by-hour weathe...", "url": "https://www.timeanddate.com/weather/usa/san-francisco", "title": "Weather for San Francisco, California, USA", "encrypted_index": "EpEBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDLV3ny+5iG5lj+Fx7xoMg90eCevgTFy1kpsHIjB8h60WGaDH3tqVBssz1eH4O4DrXcbRwGH+FvJLALFXASIBsvxqjpLZU1QRBcxLcLMqFcoibBJqujxbTeS2ipI51b8OckbjkhgE"}], "type": "text", "text": "The current weather in San Francisco is 54\u00b0F with fog, with a forecast high of 62\u00b0F and low of 49\u00b0F. Wind is 7 mph from the northeast."}], "stop_reason": "end_turn", "stop_sequence": null, "usage": {"input_tokens": 10740, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 122, "service_tier": "standard", "server_tool_use": {"web_search_requests": 1}}} \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_streaming_call_sync_events/9cb114c8-69bd-4111-841b-edee30333afd.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_streaming_call_sync_events/9cb114c8-69bd-4111-841b-edee30333afd.json deleted file mode 100644 index 0c9f8df6..00000000 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools.test_streaming_call_sync_events/9cb114c8-69bd-4111-841b-edee30333afd.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_01919EJZ2QnfiQMaJsEDgX1t\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":26,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01ACkkNu59xcFXwQQdfjR5dC\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"loca\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tion\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\": \\\"San Fran\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"cisco,\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"units\\\": \\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"f\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":74} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_01Qq1aGWEp7xgSohVeUX4bGc\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":770,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":8,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The weather in San Francisco, CA is\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" currently **\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Sunny** with a temperature of **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"68°F**.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":770,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":25} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" -] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/4a71c9f9-6191-4820-b1a1-89f3bb179078.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/4a71c9f9-6191-4820-b1a1-89f3bb179078.json new file mode 100644 index 00000000..1b7c28ab --- /dev/null +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/4a71c9f9-6191-4820-b1a1-89f3bb179078.json @@ -0,0 +1,106 @@ +[ + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:38 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk7MF3CAWoGsJWoWtwSF", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1373", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a849d968f690bc0-AMS" + }, + "body": { + "model": "claude-haiku-4-5-20251001", + "id": "msg_01W4f7BbpEG9NWkq6hifE8si", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "I'll get the weather for each of these cities one at a time. Let me start with San Francisco." + }, + { + "type": "tool_use", + "id": "toolu_01FpmqujJtkj11RDCJySJWUH", + "name": "get_weather", + "input": { + "location": "San Francisco, CA", + "units": "f" + } + } + ], + "stop_reason": "tool_use", + "stop_sequence": null, + "usage": { + "input_tokens": 701, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 96, + "service_tier": "standard" + } + } + } + }, + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:40 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk7MMiH2qTFqRNanpHUe", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1109", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a849da04ef60bc0-AMS" + }, + "body": { + "model": "claude-haiku-4-5-20251001", + "id": "msg_01NJyxkC7vtwSFZm4d3KJRUt", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "Now let me check New York:" + }, + { + "type": "tool_use", + "id": "toolu_017cDHUBfAhBDseR2vW7axod", + "name": "get_weather", + "input": { + "location": "New York, NY", + "units": "f" + } + } + ], + "stop_reason": "tool_use", + "stop_sequence": null, + "usage": { + "input_tokens": 837, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 81, + "service_tier": "standard" + } + } + } + } +] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6401445a-5758-4777-9778-3008bae873ec.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6401445a-5758-4777-9778-3008bae873ec.json new file mode 100644 index 00000000..75a2174f --- /dev/null +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6401445a-5758-4777-9778-3008bae873ec.json @@ -0,0 +1,93 @@ +[ + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:32 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk7LmzVt3Z3yYKFxpWbn", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1315", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a849d6efcbe8c7a-AMS" + }, + "body": { + "model": "claude-haiku-4-5-20251001", + "id": "msg_01S4zx3T748n7ZVrLGAGfgFS", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_01LTJ5KhgNy2y3RoyfR4dgBk", + "name": "get_weather", + "input": { + "location": "SF", + "units": "c" + } + } + ], + "stop_reason": "tool_use", + "stop_sequence": null, + "usage": { + "input_tokens": 597, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 71, + "service_tier": "standard" + } + } + } + }, + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:33 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk7LtNydsBSrctuycfL6", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1013", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a849d785e5c8c7a-AMS" + }, + "body": { + "model": "claude-haiku-4-5-20251001", + "id": "msg_01JMXwhaAsHMreUdrfoNbQKs", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "The weather in SF is currently **20°C** and **Sunny**!" + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 705, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 20, + "service_tier": "standard" + } + } + } + } +] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6cd089e9-1c08-40a5-851d-c272b3f1c248.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6cd089e9-1c08-40a5-851d-c272b3f1c248.json new file mode 100644 index 00000000..addb29c4 --- /dev/null +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6cd089e9-1c08-40a5-851d-c272b3f1c248.json @@ -0,0 +1,149 @@ +[ + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:23 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk7L32bmhx4PN5W2e674", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "2019", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a849d30391fc13c-AMS" + }, + "body": { + "model": "claude-3-5-haiku-20241022", + "id": "msg_01DXhC71psJn1RhEsecTydUB", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "I'll help you get the weather for San Francisco. I'll retrieve the temperature in Fahrenheit, which is typically preferred in the United States." + }, + { + "type": "tool_use", + "id": "toolu_01Not8sU7rvvvixVRigDz1ee", + "name": "get_weather", + "input": { + "location": "San Francisco, CA", + "units": "f" + } + } + ], + "stop_reason": "tool_use", + "stop_sequence": null, + "usage": { + "input_tokens": 424, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 104, + "service_tier": "standard" + } + } + } + }, + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:25 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk7LCRQJ2cqN2vpz4veM", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "2148", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a849d3dffa9c13c-AMS" + }, + "body": { + "model": "claude-3-5-haiku-20241022", + "id": "msg_01WeMH1D2TYPZYj7Vbm2XVDN", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "I apologize, but it seems there was an unexpected error when trying to retrieve the weather information. This can happen due to temporary system issues. Let me try again:" + }, + { + "type": "tool_use", + "id": "toolu_01LJTxn5gThzGiq5MgRfbogp", + "name": "get_weather", + "input": { + "location": "San Francisco, CA", + "units": "f" + } + } + ], + "stop_reason": "tool_use", + "stop_sequence": null, + "usage": { + "input_tokens": 557, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 109, + "service_tier": "standard" + } + } + } + }, + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:27 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk7LNPBn1Qv62UVz8PSD", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1650", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a849d4c7932c13c-AMS" + }, + "body": { + "model": "claude-3-5-haiku-20241022", + "id": "msg_01Pq1Tj1FV2uXN5mZm7sphQi", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "Great! Here's the current weather in San Francisco:\n- Temperature: 68°F\n- Condition: Sunny\n\nIt looks like a beautiful, mild day in San Francisco with sunny skies and a comfortable temperature of 68 degrees Fahrenheit." + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 705, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 59, + "service_tier": "standard" + } + } + } + } +] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6f763c87-ecb6-4217-8f6f-32db8e84a6be.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6f763c87-ecb6-4217-8f6f-32db8e84a6be.json new file mode 100644 index 00000000..eb24ec5f --- /dev/null +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6f763c87-ecb6-4217-8f6f-32db8e84a6be.json @@ -0,0 +1,183 @@ +[ + { + "response": { + "status_code": 200, + "headers": { + "date": "Fri, 05 Dec 2025 15:05:54 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVokHqKukgk86TgfHSWRn", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "3589", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a9471aa6f319a0e-AMS" + }, + "body": { + "model": "claude-haiku-4-5-20251001", + "id": "msg_01RAEMSsi4gkXbrnF8wr2FX5", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "server_tool_use", + "id": "srvtoolu_01A3t4TfPKgiXf6nKDGsD3c1", + "name": "web_search", + "input": { + "query": "SF weather today" + } + }, + { + "type": "web_search_tool_result", + "tool_use_id": "srvtoolu_01A3t4TfPKgiXf6nKDGsD3c1", + "content": [ + { + "type": "web_search_result", + "title": "San Francisco, CA Weather Forecast | AccuWeather", + "url": "https://www.accuweather.com/en/us/san-francisco/94103/weather-forecast/347629", + "encrypted_content": "EtYMCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDC6+1cF/5oGziif1JBoM4tMn+KWAS4XfwRr9IjDyPqAutmu0TuuKfrF3KDnDm8l/lLxdkQq6ZDvXnpFHP3JQ0zsT2kc6fDo+ICy08HEq2Qu4Qe8ThdDP1+SYKZXJQuA3+s23P4npfnJdsH9LGxGXn+cS0YwbtdvtcobO53L0rYQ+IZrsgqqKz5uwAXGr7leoDOUAzwLhM6hz+ZJC9q2MfdTGe9+1eHRY6gfRQx3UzDBVH0N9Wg1eAe5FttuIO3izOg7XNCf+xez0DGd6CKC6hUlP8o4VT0lvHgCfAs4vqXeFyk02AgGOoJy0DdqPQHciJfhJphuDC9fapKWi0qAGFvneizL6jZMnVf3lVM3DlSAVW5D3/pO7Sr5YkAKaEHTqqN+WY6ddFfHpTzm7n9jHnIIArrTduNUoguVtNXDe19iCrHomwv1pTIqhMSO7cAUjcjKHp8zrqMvthgB7txuw/S76J2L3XRzgijGBaHDvIWmSPaAb8nGDK/F1SjODX6lHBdR2dIa8c4ByGqIZVysQW+V1WzYCmLzCthBbuGPrWg7nn7dZPuUbew8CJv+QTmuKli6UAgLmrPKeJi6XcYKQBaAXUo+KzNPXTEnNLQ+wE6/ledc7BITc/Yb5i+UthW+jbkmmFlFu2R897S9hhLXUE4XqNVcRWMGMhxIfTTIF5y2M6lRrz4/xV1zx5aDgKncU2s7dvWbv+UwRdkx9EpYdSBjQ89ytaJKwATI8qIUWFWHATuhzs4W6edwfnBiIZhKOt8HexrklbReVqzlyk76CIRzCGUHTrShyTjpMMpGTgp3PbK4Rg6f96gXtokBrs/jKh7HSFku4I7c55oLayNh43EeXzk7JO0BlCvDV3b2r6And5q922KNeM1qaoomjHtVXVJiMWdpC4glML11PTinM/CGGRjLZ/0yVwJLjU5mLQxixVsGzg2T0+pbmoSl8PgvBRtCwKTLPeCgR86xFWtHueIrdEjc/l87Fr4DfqTtrHyGUKCcoXqO3bLqlo9eJlk64buVr5SOOnB27v6PaDDMqZ2aEsTcByntsoAFz4oVzuxgJYH4+ulSq+1NCwQVBd3nGpyVwY4lDugjQL2L3ITo7pISnMKW1gWCjVA69YWZ9t1f88sP1kuDAheBmNicTQXJFsWw0O65Ff4T+05zQ28b8EEJO42eoCJu9ZuUSWof9lqT8al77rQ/LJYsPZcHlNVgUXf03Jjs7iLqDOIkGg6qf11Xgb5wUkxZsQxLTSWezcOwgR6vVRRKQ7yedG8bP43szZc63SoH9XQDTBS1QvomGXbjM/hw8arCRKRWH+JnPnWnvQumUO0fBcfa7ugyndFJJwl/6UmOlM35RI4OrEbHH2b4vm/9h7nt4ZZ6mrTV47Xr9erXrXpi5uPYCgAynBxBpED5bfYwK0d1uw/AGa6BkeokMaNGroFvF8qIs9xNxS6gmp4AY3gJJaos+AjeGsl6iFO4zJCrrxKM++o4kp2oJVY3joAzL+2LfOb3aSarCHaPnLcq6A5I6lhjLRdBZvu54pPKYlKBzBxrk+Og7sqr458AgklGi3ZKKgO0g58dAxZB1ROy9/NbSRrmaGY+lwjE0WpaME6UVKzXOAHnQrsnlnueoVxwizkqRV5ryTQcdFuiEJbKOydMkEus5JZi4ncv6pKdo8l0V+Cq/2WU1d841ImQ3ExC5aqw0fG+IeIHM/TcDFHZ8fEjq/krINwivsR6nQYAohmF9qzNZpu3dmHChHxP/VMwAJLJV93bVu+OJCpVP20rgfTCEZUC2d9gVFaWpwcLdasYZdgpH0norbBe0WUY27apXVCj573rMGQQnhpECKm3wJBOpn20djIkarBtxO9yO8e3S+9P4YD/AQ4nxGP8nmngcnijBkvoF2zstUkbra/uvz+ggoo6370rWnEv4qgnL7BReIhKHKzsP8XzQsQvJHi0B4r4i36p0UMN8oXyQE3DDfJoNSAKMTPmEx1JyV6jVNrrjFeIM1ra80rONYnDd4JjV5pg3wf2tDmJkJqKcfHl7Yx5HHRujHC7dYZ/eMKag/nALebWxmjEUsZQNRHHCpvnVr1EBTRZGw1P9Xzn62n19cLrMGLkYAw==", + "page_age": "3 days ago" + }, + { + "type": "web_search_result", + "title": "San Francisco, CA Hourly Weather Forecast | Weather Underground", + "url": "https://www.wunderground.com/hourly/us/ca/san-francisco", + "encrypted_content": "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", + "page_age": null + }, + { + "type": "web_search_result", + "title": "San Francisco, California | Current Weather Forecasts, Live Radar Maps & News | WeatherBug", + "url": "https://www.weatherbug.com/weather-forecast/now/san-francisco-ca-94103", + "encrypted_content": "Es8FCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDNLGGckKftyYswszPxoMDmiHv3w66Sw+D0ysIjDd9n6R0C/xqnqcXZKvyR8pnGdX0esXL4zrqQ+1tOndVEBsDlOjkgUHxx/BBDNUx6Iq0gSoCPcHZysOCpOLDcVordlgS16IrElAkEbrErn2dW7qlY0GeIcQyEv6SsVv+V6p4/iKbq6lbGP3dF6D8TjCb5bRkmgYbtbG/2G0voaIx+zFdMbxp08YwkH5QCHRcFRjDw6cXYbgLLaOPfa5PgdzXZvH5t+HHJoMS12BCn3Sk/MYNwg+c6NhrdlWA9Uh+g/MGOQnvgTGq+qdEKAGKOL8Mhs8X6Idb2MRR8yJcnzSM6ZmX5hp3lxMRQ9V/29Hqvf+g6oWoamykkFHA43HbN9dAPjtYtzwfRNyE+2k0zJr4crpTi1VvBYuW8lo1g9Xdf0zF0r20x5C/yWSNVeGDA1IUkglw00O8lPcEqSxHubQXpojTJBBK1S5lGuFqZDP3pPDwmxnY9V1BsGU0O624H+Gg9zhQ1MofxM3GIYCTl1xqsCzI+7yH3xAFPhcDXhWfqb8Bxk4xFIahHXu0C9X5tGkQRJrN+KdluekV84mlhMTnDlBRgwn8CKrk+nBZSbEy7OcFiYuRiyO1/1iQwiqZBFoYI8QKyPH683hLvrTfmvWkOVwGkyDe4rL/VKWJN4EJYSNAUVS4s/jmeRBHtJBMY222wE+B5hCc/kfKG6XJ8va3mQcu/BTDEvpGh/DA/PdgVvJ9Ub1pWuEXrQMBLy7zx30wJ/3x+ByazCWj9fiDIE++7NvYqXgqo24vRlqT+AIXa/oI4ZbuZU0Wfm5jTX2J4dhKOumG1lq8FdTbD0BtjbX9TZ2z78nbrQUKlU4OWvKPmZQfQk99Euiz8W2TNnYO8ZQ3HRz+T0YAw==", + "page_age": null + }, + { + "type": "web_search_result", + "title": "Weather | KTVU FOX 2", + "url": "https://www.ktvu.com/weather", + "encrypted_content": "EtQCCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDHBQfYXedtFjXqDQDBoMUIt4GTWrKrhw6ktGIjCQ9cZg0jWCVR7wF2DcBFZwpB+m5NPAyv12rU7iRtO1nWMHMleA4UkSDJ6aoc6hszIq1wHfzXq7NONKBmbXHMjSGhbrj3WJdqW13T563jnRLVNNFBddsP0T+L5oR2LqGSxjPSrTbJms+Hux0eFyBpKqqNJMC7juWyWRyg8jJj3sRcGviB1Ka6bqiqlJcvqbuHcmYr7LWMWrYObRtIosIkHooZxPxn+LBfXLoIIjMfjrlLO1bm197xqZ67x0d1EuX9J4osJ+cFJVQR0IrZZNNFjMdDHoevsbd/15BITcDcF690Dz6F+Sy+iL2VZRMjY1UpkjXpJ9SNCVehIYhCJJkZ2eMWjPMH4w7ybRWRgD", + "page_age": "3 weeks ago" + }, + { + "type": "web_search_result", + "title": "Fog Today", + "url": "https://fog.today/", + "encrypted_content": "EpoGCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDMwOeyZE4pJY/EQKcBoMAyaukz8uXYHwk+qfIjDGhKpJ9gCAsAHBD3yOM56VwdECEgHNtsAadx0V5PHbr8GGHyXYG9wpCnRF6EiVtZ4qnQVgsTpM50aivIxkNkGSy29gfFGeYYbG/NcQSJQWqGgnzYhhtHkRDIp2whNuYhh6tREvV77X0CVxhy78m8Nts1bZK9tdWW4260INVLLaFsrCKnqy2t2VAczq3qu0qhUMlw9x7giot17fuYGs/WcXyfpZE/w4ca1h5x1PzYrAPNTBoxTJHbVA50Khob2nsBsJjbPOOMU2DFm6UoAnA5UskKU8Pv9okk1ai0W7LnnuNz4qC4Uk7qO/7OKu/zS0dtATPfXtAYxukMQlbQ5CgQVk0lH0eKrbOd4YuOjd76CfPiaulpjOu3Hj9aqKvFtcrR40qHRJBBYjhS+faO8TKg3FZAYvVETiqubgw79e2KueIMJs0zyaplFgtFXFt+fncXU+kUkf4fyUFHo5vfk+ibbnXH5ul4TanR6W//6HJmuTMmsIKBFrit6gg/wpC+hkcqn0uCFP8jGrdGeww7ZqpQpoU5NieJShqVZv/9iBV/rpitjDIqTlFpj+WW/FDYz3RvRt94KvRu9Mg/MI8bzoMQLwCLhUZyOqoUoCQE985Gol41DkQA1e3N+zapLAEdW/Z7+4RyBmSh58xoauCfT33FGp74OjnRpOh7g5t35dOShKUOhpXAYtXH7FZkPz2/FCZVJzolTUYTxqMD/EhHZfBdy+mAhvQ4Gvd8Z7sI3424ENrtYwr3BVh3iXJMbVhVzmDVEWHieUoY2nA32xXh22yKdsTNwWyHvkA4h31PizRA4B6GsKWTLR1DuDqPSWr+0xFREtk0B0KSUV4umkLX9QPIW2Cb75mwq5UzM9G+SD/uUMQyZ+4ICkt9FihnS6U1x9SaOprdLKXiR1hkB53JOuI3saEKQ8tr11L4bO11JPEs4l7K69npZ0m40NVCbiRutkJ+MYAw==", + "page_age": null + }, + { + "type": "web_search_result", + "title": "San Francisco Bay Area weather and First Alert Weather forecasts - CBS San Francisco", + "url": "https://www.cbsnews.com/sanfrancisco/weather/", + "encrypted_content": "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", + "page_age": "4 weeks ago" + }, + { + "type": "web_search_result", + "title": "San Francisco, CA Current Weather - The Weather Network", + "url": "https://www.theweathernetwork.com/en/city/us/california/san-francisco/current?_guid_iss_=1", + "encrypted_content": "EpwCCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDPyCIpf18wmD2HpT3xoMTFduigKcaaj2EH0cIjAqHqZeoD5ISXHF5bJmC7m45trOlI9caV2BwXvmkbczUVstau4WjEHCnoVC8E7gC8UqnwEX/hr/LOOmDMks7MMNkqQrDte2Prh4DaJkKC3yoacmNV/6spCSSq01u41FKnBeHZNIvY9QYxQ5nZXcSPbwHqy1P+XLL3i/CWH7hFHFA8Kq2U8u2tn6ZynOMjRBEH/4c3PulDfrfFUuR1uRA1UNCObKn8s0JZEnQijWzD6HEL+Vr4YxYDC4aJesMu9xpHjC8zHZ38/dbfs1KRQyEDhNeMcYAw==", + "page_age": "4 days ago" + }, + { + "type": "web_search_result", + "title": "San Francisco Bay Area, CA", + "url": "https://www.weather.gov/mtr/", + "encrypted_content": "Ep0SCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDF2x/OG3itDlTRUxghoMcSmptqFHYPoUs9phIjBUHKoxqoEx9yuCo67rdaKPiCwWrF0EkvmPj4sslPNSFRvxWlfx/MMdGMtrhMXPiYYqoBGlf/B1yf3+PLdwCjR012EqMYdXHxySVzhoYDTCY7xHVO1sXIGNF8PoB8YKqDi2o9TSkApeT6bLkHhwL8BCi3g1eYDaID06bOtLa1OttniQwd7EyBalJvPJ1KoZ+YfWlnc3KvfUc1zgnYDt29534ltLZnKDimHK4z3RMEKLrbiewmzW5Inp1wmFLA7R7HL6OQ/aWocqJ6J27cCUrKyceOR54bHltp/7UolJoP6ZyeWqCrc6lHFC6IRu6BDsBcVHbRlySOlUJyhZnB+nFtmF9rgxAEdmv5pVEXlHPDEjAcq1oDvy+qX+qtGwkIo3oF+gAFl+qGonaz9PgWjEdlhJMUweldc4cqq6eTiHS3HcZ0QZVs5D1BTqJQOhv/ZdaKblTjwjcWpUMIY6PEUm/pktz/8a7E889euKZMIF2FdaLMqhxeM9euJ5cm01hwaxQlDZT9MOF2vfZAaS9/N8o4bmmEF7eCeBCBQOpPfXCbSulDT8Jcm2NbApDEzTTjCN1kC38X312DCkngSDTQw9ZDhTobdQZDingwiU+SvAeROotGimLT/ed4iKgl5FZYFZk6b1CzK5pRIljo5rsLbr00czJMkY25QgO0f5z3+8TSvUGORrzx2H7U+QYC1vN1yDkxBotpinkwJsaLUiEM3zJv+6GYLYeRcXn2KIY2MHgWqYBDems9Q1bvPDNbSG/IGIrCjIt7zsE69zfdwf8QFY0V/c6UgUDr31s7goaJLX/208d4J9qDUO8leGlpf+DMOCXoJxsP0fbc8lfewbGkgI6N7+54Upu+d4S4P5GIHrCoLNaFoRa/pV9fpw+EmSCW5frNC4fW/aAkdC/VxspAJHmye8UmBBxhH8h3E4Op7gN+8kuFsWmSpWwMIXGNsVzO6JdyrsmiXAiVpNhTn+QkYhqXwjNoCqhWNaI8Vv5Ppn/9sg8S8A4uexafeYDjM/qK5pLys85sccAXYkT6FoSQQ61QfDhOUm/VWOAd3l2FYWt5S6NqUbuPfmSUl1oAN2BrKIUD2dkwBBis/VC54XoPn6EHCGCoa0U9iTMklTurJVzvLk80S57eCSFCk7yP9Ep7j7+ArM4D0Qqdk745ZW+zM+Mr43xBdIfPSN7+Y9H2D6oYgWzq0EcvkRSRePkh23fhsmJSU9dNspTGjTttAxuAo+74BPuZMv1pJ5rxjFrIArtFHKi0fx2pLHX3giUpZNY9uD4xj9VrdeE4h64j4KILne/HiuqERDkgB05OZDwR9hdWlxroAhKfmx9r5pE2tuNhmIQYGMDsNhwJCzezWVnFcEz00eA9ttr5QmDnHfHOqRs+5pTtSDlqYWycwAy6nLsNeR2eUZLkAqZJZsqbEdeJ7IZC3okJEE0TX7mGHJUtAXd7uCoBzbjPExrvMjGhYFZU//bmbHclj41lKjHG2PgD8x39eCf7b0sWsYQG3y4qBppi4A5/INlClxhPnfEdXJBuilRCumgw6pYM2b00OQDOy0oS2AasAgX80mC99m1x0OMRWtSEOCgvROjfbmCzDf7h9XjcPR0iVLx1UzNJgsC5YV276mO7e7ZqZvV8B9vzobCwD8K/jyHjHc2vNyRZVnO40La9JOvQ+o2bk5W+BGFm54nmrIJXVrSSrGI50pKMCUKZzXTw21Upd8OvGlqSM1VgbkVUjQ9EcBJJ7su2KGltbR10qE4Q85M6eybsUVtG/A0wwjmPJIccYC1djyhZ5PABfBbu16bHka8BpBOR/gx5163n55iT4N2W6KcayNoYUfgJkJ5cXkNUXl1ngZeLxx47DNz/0ZxCt6+RiAAx2cRBCrCaG48XmTfmZNi/tGOFLFs/XByMu4bGAYm7/pAlUkQwhPOMJxqBssOxRt3EDQIGFMF9WfN7RRdhv+vaRbWHOE+PyNBsZymswLJA/yR9tE+kHpGy6bgLtCKFWBQnKJ6DOBL6lplDnblMkc9WQ8mvKkS9/E27gflupcvoJLNtvjKIOrdg6Njx7qsWMWwKI0LZeWtlSSU8OFAFuLb0jrRMbnZ4vjDeGty/mYdFTMW2KtHlN8Zv6G+lswD6mzUqHm1Z9nw3YHyREcha2l3qFybgcciguj6yrH5e76wXVcJbao7Fr0PRW8Ybpp4mxRv87dLNA1oA5bZPNzLZl6uBlKmZZT7K2HPzmquiWh8lgu2yUslKXCjHiGklBOFOY3739VROOgZ2OVzlpMBDBzDNoB5k0HKtQK+9LsOcaF1i47upzgzDGidTSDbtrYBjYt8kANrUEuMKX0ooLkCIYAxFDnoBc/rDNC01FMyY7VHzwQwxzQeeK6FM1x2rWstYKGEk/rpp0xZ4kc1ALH/F7hx2P6EzraJKEEyAJ05aeqyfrQEk/lxo/jplOH2rxZxKMr3F6nZOYOL0jyXAlgCvdrm1NCaUfvX6yh+Gk24ooVrSlSVMxR0pHQSzEIKoQXorQG4ex0U0jWOTx0oAigGXJSlp7nxts7BrJW4m2j9RP7a1U1bjQDkSBOhBKl7XF4oDgMrtbvB1hoW5zswWlqQmrzguZ1HfmBINTB78ig37zjZpPbBFWA5hoVmJkGtA0E7T+JAhwmT5jvQ2e4KEPbK5AEtNqwVo1yb2rB3v5dTAKZ1A1+R/J+rImKPOfpbrWAQ4MQwtQy+1xs4YiMmtNEe/3rS6IKnPB7ghILf5A1LaHZaq8qD5U4s5KexIJ1L/6ZUGq/Tm0PS76z6FK+IBCjMLvzDeu5bRKZ91l4pIUqnPI7LPB3VEg87AFtUedlg40gug6mnKUewpjNDvHNBZQhNvHdaJdzr/n4RhxkO217qvD4pveyjU/kVwAOgywrnywIX0aNYGoyUmO3YaflPmCN1Q2cZFrg/H7bUicORGPUE9zVWGvg9I505ZPswbuYJ1NkEo/1Mjm5kHNjlRnKyrgQ8pvhYUjZdgIsT6Et9YhwGg3OY+3LApiyevKTBQ0kngwYAw==", + "page_age": "2 days ago" + }, + { + "type": "web_search_result", + "title": "San Francisco Bay Area weather forecast – NBC Bay Area", + "url": "https://www.nbcbayarea.com/weather/", + "encrypted_content": "EsMICioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDLWt5CNE5+gd82RwBBoMihbjGRpjOMvBC+/rIjD6iKDuNo8ZRmIjMrToH9UflyCKZS1OpmD6kSF8elrc/8eXnUoEqR9kFJKzc10nfP4qxgfkkn2d1VG8OfKx3bX8XOJd4A7CfATqIk0i1ONXaIck1+Ts9hYU729hjbmNzup2uspCIxezHDTG/BkLFQc7Aa+kWExbAZHXcmotGOjdLjldyI+129pTuZEHav1sY9yazcmI0qpzJ0kRISwPtN5SnEycKVD7nEUR004HxDG/2BSO0cYLfBIJ0W2pVm19aUi7kCoFSl1UmwEEgOA3BN1J1ms+3P6gGuF9LIsjnVLM4omv9G3cN0YeR6h9LUMpFXQMbPRRXAzfdJKe0zc05r+4Wq0DkvNFfdKL7d23AIcObDFEAst7rSu7X2oJz7zosS0WsyKvYer/ss948tehjne4qGfEZfySMjoNlW1WnLNjWNo57IwAwOdVOyFYfUSnn7MI7l7mjhKg8NeHMVBj/fYFHimEaBsd78QIL1wIGnerku98wDiE9+s7mZwXM3vKh/ppn9TvgOB1C76UKuOaYWGCWaUaYFA9jrgnEg/GIgGZMqmrCpe9xUwsVopkg0Rk82I1lGC/Uyumu+X7FZYrixuhCh/IvlWSpkiUzaGwQGD/wQnkZc/NU1pWKR1yNlkGVbyQV155YWINOXvxyY76FvVKYJYDaRjQjpI74lYToNUK+ucVht0j71iKEus/9Ki6AMFS0606P5Pgzp/wxhJJPN9GQioH4UWNyk8zJBkWgyJGQVMQj/wUCQydFiE2lwe9vpb9/Xhbidem0mnbSIbTufVPluxfYeTNJPhB/aJd6xLQL7cDcHquHbUprXgyBFeYnoSzfdDMmH3AFkXsyvAF94+HiF1gIUCJxCm3W5WK8PiXsAlUul8ySYhXsJbXd2ojRIg6rwIzqsdmh33sWZx88Xwi78Pmn+6J7NzakEVGVj6+5wH17PTXtdln2Nd22QOzvn6SWmyyv50GwxpdEluMnAeyzzkkp6zGrBoSpKFHzjqrjYBiXbQWMut1+q0lK0b1SRTOChWCDjuG7FedM/n1yx4Zs/WYRauSn4DBBzU0OmvD0rcZGQPaHkXbh7PqNBZW4yVhSIO22MnlrN8flUWdJUK4xDGpTXeBtjh8eiwu9fk4+ACqWhxyjvNyrcfhcV8ScmG1tKFjsU8C2Z817zjqPiXcDSRrhJ5b35banK5n/2Yv47PAQXnfjNlDk4s9b49PhIaN5WnXLJSWpJZpz1zY5Ct7kF8ZzYPsqgSFPCcbEtCN/QEpLsZLfvZM1JYMUknWwrt5EGGrmGK9dqhOpOLBccWQ0yAEXzE8UbfuWS26ZttHO01ZCzzookNVB/0342QCCI3Op7Za3udzQoUYAw==", + "page_age": "3 days ago" + }, + { + "type": "web_search_result", + "title": "San Francisco, CA Weather Forecast, Conditions, and Maps", + "url": "https://www.yahoo.com/news/weather/united-states/california/san-francisco-2487956", + "encrypted_content": "EswBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDFQaQjU3YjkQyuhdkBoMb/hFX/Eppc86YUC5IjABwWR/z3hhZ/1IOYeauzdY38Mc5cBeKJQaiNeYaG5mfhwxCZ0icRVJm5bw6zjbpIQqUD036oskC4KdqLkBFUyYwxJcc/EbdxXDNyb0Qv6IBBa6PHS/PvLkMFuXoBx7YYDFh6f6b9dSDpio9Jjtps/1o/4RMpBknxqLvxs5x+utHWSsGAM=", + "page_age": null + } + ] + }, + { + "type": "text", + "text": "Based on the current weather forecast for San Francisco:\n\n" + }, + { + "citations": [ + { + "type": "web_search_result_location", + "cited_text": "zoom out · Showing Stations · Hourly Forecast for Today, Friday 12/05Hourly for Today, Fri 12/05 · Today 12/05 · 6% / 0 in · A good deal of sunshine. ", + "url": "https://www.wunderground.com/hourly/us/ca/san-francisco", + "title": "San Francisco, CA Hourly Weather Forecast | Weather Underground", + "encrypted_index": "Eo8BCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDF3vaU6EU5iBxOhrQRoMFYIQ8+XE15PuZ0pKIjA4FQSdosGf5L6Ol7fIfpIJy5lid8Uy84RIIDuicPTQXDGtRjCWuP3CnNDVv36D3ZcqEzEyHm/WXGjf92QPwdyhgZaoFv0YBA==" + } + ], + "type": "text", + "text": "Today is expected to have a good deal of sunshine" + }, + { + "type": "text", + "text": ", with " + }, + { + "citations": [ + { + "type": "web_search_result_location", + "cited_text": "High 58F. Winds N at 5 to 10 mph. ", + "url": "https://www.wunderground.com/hourly/us/ca/san-francisco", + "title": "San Francisco, CA Hourly Weather Forecast | Weather Underground", + "encrypted_index": "EpEBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDBwrHoCSxWPWRdrHcRoMHH5lBQOZwtO5+k3ZIjC8kOWVDaoLDQ3MIbdxZvI+A/1U4V+LsjOwGwXfeg7+HfnQzYBCygEh6mN6YJPxwAgqFXGba3zldKQEEGzVniRgCiaAxyOs6BgE" + } + ], + "type": "text", + "text": "a high of 58°F and winds from the north at 5 to 10 mph" + }, + { + "type": "text", + "text": ". " + }, + { + "citations": [ + { + "type": "web_search_result_location", + "cited_text": "Tonight 12/05 · 8 % / 0 in · Partly cloudy skies. Low 47F. ", + "url": "https://www.wunderground.com/hourly/us/ca/san-francisco", + "title": "San Francisco, CA Hourly Weather Forecast | Weather Underground", + "encrypted_index": "EpEBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDOjg/daPzBMpVqtcBRoMFvN5srtrqjEwD4K9IjCOroiNwibFTmcvkWIaB32TxH8phnMjZJlXqBRfLN5USQuslXbr9vIEz21IMJzVqrcqFfb09hoAOJn6U7was5gtdsojZeftwRgE" + } + ], + "type": "text", + "text": "Tonight will be partly cloudy with a low of 47°F" + }, + { + "type": "text", + "text": "." + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 9656, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 176, + "service_tier": "standard", + "server_tool_use": { + "web_search_requests": 1 + } + } + } + } + } +] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ad005e89-f72b-4f0e-941a-9ec3473c1bc8.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ad005e89-f72b-4f0e-941a-9ec3473c1bc8.json new file mode 100644 index 00000000..4dfa3aa7 --- /dev/null +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ad005e89-f72b-4f0e-941a-9ec3473c1bc8.json @@ -0,0 +1,93 @@ +[ + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 17:23:46 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk9BvJJL9DSpQAbDcRJA", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1525", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a84c0eb5eeb656e-AMS" + }, + "body": { + "model": "claude-haiku-4-5-20251001", + "id": "msg_017qL8GBMqwCsEmXujM6p775", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_01EqKdVnvSZkNUXcxkJZsva7", + "name": "get_weather", + "input": { + "location": "San Francisco, CA", + "units": "f" + } + } + ], + "stop_reason": "tool_use", + "stop_sequence": null, + "usage": { + "input_tokens": 656, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 74, + "service_tier": "standard" + } + } + } + }, + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 17:23:47 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk9C3uCDkHzzBQZKzQ5h", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1453", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a84c0f65f6c656e-AMS" + }, + "body": { + "model": "claude-haiku-4-5-20251001", + "id": "msg_01FvTMNojoLmBYw4KxJXB27y", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "The weather in San Francisco is currently **68°F and Sunny**. Great day to be out and about!" + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 770, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 27, + "service_tier": "standard" + } + } + } + } +] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/e4c374b8-ae08-48f3-96e5-9d28066820b0.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/e4c374b8-ae08-48f3-96e5-9d28066820b0.json new file mode 100644 index 00000000..47ee9758 --- /dev/null +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/e4c374b8-ae08-48f3-96e5-9d28066820b0.json @@ -0,0 +1,96 @@ +[ + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 17:00:10 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk7N2gZrR5LZ96asq2gB", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "22362", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a849dd93c6bae1c-AMS" + }, + "body": { + "model": "claude-sonnet-4-5-20250929", + "id": "msg_01E3KgQxmugcS6yfwKeWkXz1", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "# The Fascinating World of Dogs, Cats, and Birds: A Comparative Look at Popular Pets\n\nThroughout human history, animals have played pivotal roles in our lives, serving as companions, helpers, and sources of joy. Among the most beloved creatures that share our homes are dogs, cats, and birds—three distinctly different yet equally captivating groups of animals that have captured hearts worldwide.\n\n## Dogs: Humanity's Loyal Companions\n\nDogs, scientifically known as Canis familiaris, have earned their reputation as \"man's best friend\" through thousands of years of domestication. Descended from wolves, dogs have evolved alongside humans for approximately 15,000 to 40,000 years, developing an unparalleled bond with our species. Their remarkable diversity is astounding, with over 340 recognized breeds ranging from the tiny Chihuahua to the massive Great Dane.\n\nWhat sets dogs apart is their exceptional loyalty and trainability. They possess an innate desire to please their owners, making them ideal working animals in roles such as service dogs, police dogs, and therapy animals. Their acute sense of smell—up to 100,000 times more sensitive than humans—and keen hearing make them excellent guardians. Dogs are highly social creatures that thrive on interaction, requiring regular exercise, mental stimulation, and consistent companionship to maintain their physical and emotional well-being.\n\n## Cats: Independent Yet Affectionate\n\nCats, or Felis catus, present a fascinating contrast to their canine counterparts. These elegant felines were domesticated more recently, approximately 9,000 years ago in the Middle East. Unlike dogs, cats retain much of their wild independence, making them perfect companions for those who appreciate a more autonomous pet.\n\nCats are renowned for their grace, flexibility, and hunting prowess. Their retractable claws, exceptional night vision, and lightning-fast reflexes make them formidable predators of small prey. Despite their reputation for aloofness, cats form strong bonds with their owners, expressing affection through purring, head-butting, and kneading. They are relatively low-maintenance pets, being naturally clean animals that groom themselves meticulously and can be easily litter-trained. Cats are ideal for apartment living and busy individuals, as they require less direct attention than dogs while still providing meaningful companionship.\n\n## Birds: Colorful and Intelligent\n\nBirds represent an entirely different category of pet ownership, offering unique rewards and challenges. From small budgerigars to large parrots like macaws and African greys, pet birds display remarkable intelligence and personality. Many species can learn to mimic human speech and perform complex tricks, demonstrating cognitive abilities that rival some mammals.\n\nBirds are social creatures in the wild, and pet birds require significant mental stimulation and interaction to thrive. Their vibrant plumage, melodious songs, and playful behaviors bring joy and liveliness to any home. However, bird ownership demands commitment—proper housing, specialized diets, and regular veterinary care are essential. Some larger parrot species can live for 50 years or more, making them lifetime companions.\n\n## Conclusion\n\nDogs, cats, and birds each offer distinct advantages as companion animals. Dogs provide unwavering loyalty and active companionship, cats offer independent yet affectionate relationships, and birds deliver intelligence and beauty in compact packages. The choice between these wonderful creatures ultimately depends on individual lifestyle, living situation, and personal preferences, but all three have proven themselves as irreplaceable members of countless families worldwide." + }, + { + "type": "tool_use", + "id": "toolu_01M3sFZ6BzuiJc7mqwv79u8e", + "name": "submit_analysis", + "input": { + "summary": "This comprehensive essay explores three popular categories of companion animals: dogs, cats, and birds. Dogs (Canis familiaris) are highlighted as loyal, trainable companions domesticated 15,000-40,000 years ago, with over 340 breeds and exceptional abilities in smell and hearing, making them ideal service and working animals. Cats (Felis catus) are presented as independent yet affectionate pets domesticated around 9,000 years ago, known for their grace, hunting abilities, low-maintenance nature, and self-grooming habits. Birds, ranging from budgerigars to large parrots, are described as intelligent and colorful pets capable of mimicking speech and performing tricks, requiring significant mental stimulation and potentially living 50+ years. The essay emphasizes that each animal type offers unique advantages: dogs provide active companionship and loyalty, cats offer independent relationships suitable for busy lifestyles, and birds deliver intelligence and beauty. The choice among these pets depends on individual lifestyle, living situation, and personal preferences, with all three serving as beloved family members worldwide." + } + } + ], + "stop_reason": "tool_use", + "stop_sequence": null, + "usage": { + "input_tokens": 617, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 1046, + "service_tier": "standard" + } + } + } + }, + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 17:00:24 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk7Ph89FopGzZt9w21Em", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "13504", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a849e663eb0ae1c-AMS" + }, + "body": { + "model": "claude-sonnet-4-5-20250929", + "id": "msg_01DAVpeXCGJPScdQDECVbF8z", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "\n## 1. Task Overview\nThe user has requested:\n- Write a detailed 500-word essay about dogs, cats, and birds\n- Call the tool `submit_analysis` ONCE at the end with information about all three animals\n- The tool should contain compiled information from the essay about all three animal types\n\nSuccess criteria:\n- Essay must be approximately 500 words\n- Must cover all three animals (dogs, cats, birds)\n- Must be detailed\n- Single tool call at the very end containing analysis/information about all three animals\n\n## 2. Current State\n**Completed:** Nothing has been completed yet.\n\n**Files/Outputs:** None created.\n\n**Status:** Task not started. No essay has been written, and no tool has been called.\n\n## 3. Important Discoveries\nNo technical constraints have been uncovered yet, as work hasn't begun.\n\n**Key requirements identified:**\n- Need to understand the `submit_analysis` tool parameters (what fields it accepts)\n- The tool call should synthesize information about all three animals from the essay\n- Only ONE tool call should be made, despite covering three different animals\n\n## 4. Next Steps\n**Immediate actions required:**\n\n1. **Write the 500-word essay** covering:\n - Dogs (characteristics, behavior, role as pets, etc.)\n - Cats (characteristics, behavior, role as pets, etc.)\n - Birds (characteristics, behavior, role as pets, etc.)\n - Ensure balanced coverage of all three animals\n - Aim for approximately 500 words total\n\n2. **Call `submit_analysis` tool once** after completing the essay:\n - Structure the tool call to include information about all three animals\n - Likely format: summarize key points about each animal type\n - May need to check tool schema to understand expected parameters\n\n**Priority:** Write essay first, then make single tool call.\n\n**Blockers/Questions:** \n- Need to determine exact parameters for `submit_analysis` tool when ready to call it\n\n## 5. Context to Preserve\n- User specifically emphasized calling the tool \"only once at the end\"\n- Essay should be \"detailed\" - aim for substantive content, not superficial\n- All three animals must be covered adequately\n- Word count target: approximately 500 words\n" + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 324, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 518, + "service_tier": "standard" + } + } + } + } +] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f1c3350a-cdb1-4508-a208-18544b825a9e.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f1c3350a-cdb1-4508-a208-18544b825a9e.json new file mode 100644 index 00000000..7844334f --- /dev/null +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f1c3350a-cdb1-4508-a208-18544b825a9e.json @@ -0,0 +1,93 @@ +[ + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:29 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk7LXBWiTyE1QTrPLnAX", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1669", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a849d594f6bef02-AMS" + }, + "body": { + "model": "claude-haiku-4-5-20251001", + "id": "msg_01A5yigixNUyniQWth6shEDJ", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_01LqkbUvG3bxuFskR83MavPX", + "name": "get_weather", + "input": { + "location": "San Francisco, CA", + "units": "c" + } + } + ], + "stop_reason": "tool_use", + "stop_sequence": null, + "usage": { + "input_tokens": 659, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 74, + "service_tier": "standard" + } + } + } + }, + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:30 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk7Lf5mkssVqmBu1ELdx", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1270", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a849d64d8a1ef02-AMS" + }, + "body": { + "model": "claude-haiku-4-5-20251001", + "id": "msg_01K4waJ1jAaJvWS9uatX5ANU", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "The weather in San Francisco, CA is currently **sunny** with a temperature of **20°C**." + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 763, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 24, + "service_tier": "standard" + } + } + } + } +] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f27add0c-5771-4452-8ed9-996f5d74ef77.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f27add0c-5771-4452-8ed9-996f5d74ef77.json new file mode 100644 index 00000000..e2740b38 --- /dev/null +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f27add0c-5771-4452-8ed9-996f5d74ef77.json @@ -0,0 +1,42 @@ +[ + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:41 GMT", + "content-type": "text/event-stream; charset=utf-8", + "connection": "keep-alive", + "cf-ray": "9a849daa3cc7c96e-AMS", + "cache-control": "no-cache", + "request-id": "req_011CVk7MUVpHYeAtqMB2wjEf", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1027", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare" + }, + "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_0128e4yzgSDzgbfodAq3mig6\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":3,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll look\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" up the weather in San Francisco for you\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\".\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01BxxZChiKMMRsAWwPDpTQdT\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"l\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"oca\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tion\\\": \\\"San\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Francisco\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"unit\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s\\\": \\\"f\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":86} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" + } + }, + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:47 GMT", + "content-type": "text/event-stream; charset=utf-8", + "connection": "keep-alive", + "cf-ray": "9a849db43dcbc96e-AMS", + "cache-control": "no-cache", + "request-id": "req_011CVk7MbUksXDMu1D37oqFh", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "5241", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare" + }, + "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_017jipFcWV4GbthdYcheFtK8\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":782,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":6,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The weather in San Francisco,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" CA is currently\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Sunny**\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" with a temperature of **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"68°F**\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" (about\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" 20°C).\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":782,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":32} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" + } + } +] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ff848716-2309-477f-8e90-39877809aaad.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ff848716-2309-477f-8e90-39877809aaad.json new file mode 100644 index 00000000..7375b84b --- /dev/null +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ff848716-2309-477f-8e90-39877809aaad.json @@ -0,0 +1,42 @@ +[ + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:35 GMT", + "content-type": "text/event-stream; charset=utf-8", + "connection": "keep-alive", + "cf-ray": "9a849d813ddb8072-AMS", + "cache-control": "no-cache", + "request-id": "req_011CVk7LzRrjy32aXFeDdL6v", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1378", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare" + }, + "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_01SAGfXDtnWyD3j4h5Wz3kky\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":26,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01LZ7WbFLVzFd16Ur9RHXeGz\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"loca\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tion\\\": \\\"Sa\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n Fran\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"cisco, CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"units\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \\\"f\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":74} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" + } + }, + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 16:59:36 GMT", + "content-type": "text/event-stream; charset=utf-8", + "connection": "keep-alive", + "cf-ray": "9a849d8c5b1d8072-AMS", + "cache-control": "no-cache", + "request-id": "req_011CVk7M8411PnGQs9cMkqBD", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1001", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare" + }, + "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_01ERB2ekevEhTbZtAuM2HjmS\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":770,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":8,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The weather in San Francisco, CA is\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" currently\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"68\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"°F an\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"d Sunny**\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"☀️\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":770,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":24} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" + } + } +] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/__module__/c4061e82-ea59-4756-9549-71a35da24499.json b/tests/lib/tools/__inline_snapshot__/test_runners/__module__/c4061e82-ea59-4756-9549-71a35da24499.json new file mode 100644 index 00000000..02591586 --- /dev/null +++ b/tests/lib/tools/__inline_snapshot__/test_runners/__module__/c4061e82-ea59-4756-9549-71a35da24499.json @@ -0,0 +1,93 @@ +[ + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 17:23:39 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk9BQEnYiTudQzWPwnzN", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1595", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a84c0bf4b66ffef-AMS" + }, + "body": { + "model": "claude-haiku-4-5-20251001", + "id": "msg_014mVBfXF9GXKArtHjdvxo4K", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "tool_use", + "id": "toolu_01V6B73Yme2e4g9zjtz2ysgG", + "name": "get_weather", + "input": { + "location": "San Francisco, CA", + "units": "f" + } + } + ], + "stop_reason": "tool_use", + "stop_sequence": null, + "usage": { + "input_tokens": 656, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 74, + "service_tier": "standard" + } + } + } + }, + { + "response": { + "status_code": 200, + "headers": { + "date": "Wed, 03 Dec 2025 17:23:40 GMT", + "content-type": "application/json", + "connection": "keep-alive", + "request-id": "req_011CVk9BYLheDJYWkdFPeuMQ", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", + "x-envoy-upstream-service-time": "1067", + "cf-cache-status": "DYNAMIC", + "x-robots-tag": "none", + "server": "cloudflare", + "cf-ray": "9a84c0cb2e4dffef-AMS" + }, + "body": { + "model": "claude-haiku-4-5-20251001", + "id": "msg_013CAacn66fhBYyjs4T6g4jV", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "The weather in San Francisco, CA is currently **68°F and Sunny**. Nice weather!" + } + ], + "stop_reason": "end_turn", + "stop_sequence": null, + "usage": { + "input_tokens": 770, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 24, + "service_tier": "standard" + } + } + } + } +] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/test_streaming_call_sync_events/9cb114c8-69bd-4111-841b-edee30333afd.json b/tests/lib/tools/__inline_snapshot__/test_runners/test_streaming_call_sync_events/9cb114c8-69bd-4111-841b-edee30333afd.json deleted file mode 100644 index 745be1e3..00000000 --- a/tests/lib/tools/__inline_snapshot__/test_runners/test_streaming_call_sync_events/9cb114c8-69bd-4111-841b-edee30333afd.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_01DfDUn6fFzYyGNjmWmA9XVK\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-3-5-sonnet-20241022\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":473,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":2,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" help you check the weather in San Francisco\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\". Since the location parameter needs to be more\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" specific, I'll use \\\"San Francisco, CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" and I'll show you the temperature in both\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" Celsius and Fahrenheit.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01QYZ2sgjBq1oG8iryEt8QjR\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"location\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"San Francisc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"o, CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"unit\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s\\\":\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \\\"c\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1 }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01Lu9hbRKgrZqvHFutZxCNnZ\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"loc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"at\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"io\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n\\\": \\\"San \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"Francisco\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"units\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"f\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":473,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":176} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n", - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_014L4v4PaF8RoEXeryKARnCp\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-3-5-sonnet-20241022\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":767,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":2,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" weather in San Francisco, CA is\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" currently sunny with a temperature of 20\u00b0C (68\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"\u00b0F).\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":767,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":27} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" -] \ No newline at end of file diff --git a/tests/lib/tools/test_runners.py b/tests/lib/tools/test_runners.py index 7575deba..c73a9715 100644 --- a/tests/lib/tools/test_runners.py +++ b/tests/lib/tools/test_runners.py @@ -1,10 +1,9 @@ import json import logging -from typing import Any, Dict, List, Union +from typing import Any, Dict, List, Union, cast from typing_extensions import Literal, TypeVar import pytest -from respx import MockRouter from inline_snapshot import external, snapshot from anthropic import Anthropic, AsyncAnthropic, beta_tool, beta_async_tool @@ -17,68 +16,21 @@ from anthropic.types.beta.beta_tool_result_block_param import BetaToolResultBlockParam from ..utils import print_obj -from ...conftest import base_url -from ..snapshots import make_snapshot_request, make_async_snapshot_request, make_stream_snapshot_request _T = TypeVar("_T") -# all the snapshots in this file are auto-generated from the live API -# +# all the snapshots in this file are auto-generated from the live API, # you can update them with -# -# `ANTHROPIC_LIVE=1 ./scripts/test --inline-snapshot=fix -n0` - -snapshots = { - "basic": { - "responses": snapshot( - [ - '{"model": "claude-haiku-4-5-20251001", "id": "msg_0133AjAuLSKXatUZqNkpALPx", "type": "message", "role": "assistant", "content": [{"type": "tool_use", "id": "toolu_01DGiQScbZKPwUBYN79rFUb8", "name": "get_weather", "input": {"location": "San Francisco, CA", "units": "f"}}], "stop_reason": "tool_use", "stop_sequence": null, "usage": {"input_tokens": 656, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 74, "service_tier": "standard"}}', - '{"model": "claude-haiku-4-5-20251001", "id": "msg_014x2Sxq2p6sewFyUbJp8Mg3", "type": "message", "role": "assistant", "content": [{"type": "text", "text": "The weather in San Francisco, CA is currently **68\\u00b0F** and **Sunny**. It\'s a nice day! \\u2600\\ufe0f"}], "stop_reason": "end_turn", "stop_sequence": null, "usage": {"input_tokens": 770, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 33, "service_tier": "standard"}}', - ] - ), - "result": snapshot( - "ParsedBetaMessage(container=None, content=[ParsedBetaTextBlock(citations=None, parsed_output=None, text=\"The weather in San Francisco, CA is currently **68°F** and **Sunny**. It's a nice day! ☀️\", type='text')], context_management=None, id='msg_014x2Sxq2p6sewFyUbJp8Mg3', model='claude-haiku-4-5-20251001', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=BetaUsage(cache_creation=BetaCacheCreation(ephemeral_1h_input_tokens=0, ephemeral_5m_input_tokens=0), cache_creation_input_tokens=0, cache_read_input_tokens=0, input_tokens=770, output_tokens=33, server_tool_use=None, service_tier='standard'))\n" - ), - }, - "custom": { - "responses": snapshot( - [ - '{"model": "claude-haiku-4-5-20251001", "id": "msg_01FKEKbzbqHmJv5ozwH7tz99", "type": "message", "role": "assistant", "content": [{"type": "text", "text": "Let me check the weather for San Francisco for you in Celsius."}, {"type": "tool_use", "id": "toolu_01MxFFv4azdWzubHT3dXurMY", "name": "get_weather", "input": {"location": "San Francisco, CA", "units": "c"}}], "stop_reason": "tool_use", "stop_sequence": null, "usage": {"input_tokens": 659, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 88, "service_tier": "standard"}}', - '{"model": "claude-haiku-4-5-20251001", "id": "msg_01DSPL7PHKQYTe9VAFkHzsA3", "type": "message", "role": "assistant", "content": [{"type": "text", "text": "The weather in San Francisco, CA is currently **20\\u00b0C** and **Sunny**. Nice weather!"}], "stop_reason": "end_turn", "stop_sequence": null, "usage": {"input_tokens": 787, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 26, "service_tier": "standard"}}', - ] - ), - "result": snapshot( - "ParsedBetaMessage(container=None, content=[ParsedBetaTextBlock(citations=None, parsed_output=None, text='The weather in San Francisco, CA is currently **20°C** and **Sunny**. Nice weather!', type='text')], context_management=None, id='msg_01DSPL7PHKQYTe9VAFkHzsA3', model='claude-haiku-4-5-20251001', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=BetaUsage(cache_creation=BetaCacheCreation(ephemeral_1h_input_tokens=0, ephemeral_5m_input_tokens=0), cache_creation_input_tokens=0, cache_read_input_tokens=0, input_tokens=787, output_tokens=26, server_tool_use=None, service_tier='standard'))\n" - ), - }, - "streaming": { - "result": snapshot( - "ParsedBetaMessage(container=None, content=[ParsedBetaTextBlock(citations=None, parsed_output=None, text='The weather in San Francisco, CA is currently **Sunny** with a temperature of **68°F**.', type='text')], context_management=None, id='msg_01Vm8Ddgc8qm4iuUSKbf6jku', model='claude-haiku-4-5-20251001', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=BetaUsage(cache_creation=BetaCacheCreation(ephemeral_1h_input_tokens=0, ephemeral_5m_input_tokens=0), cache_creation_input_tokens=0, cache_read_input_tokens=0, input_tokens=781, output_tokens=25, server_tool_use=None, service_tier='standard'))\n" - ) - }, - "tool_call": { - "responses": snapshot( - [ - '{"model": "claude-haiku-4-5-20251001", "id": "msg_01NzLkujbJ7VQgzNHFx76Ab4", "type": "message", "role": "assistant", "content": [{"type": "tool_use", "id": "toolu_01SPe52JjANtJDVJ5yUZj4jz", "name": "get_weather", "input": {"location": "SF", "units": "c"}}], "stop_reason": "tool_use", "stop_sequence": null, "usage": {"input_tokens": 597, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 71, "service_tier": "standard"}}', - '{"model": "claude-haiku-4-5-20251001", "id": "msg_016bjf5SAczxp28ES4yX7Z7U", "type": "message", "role": "assistant", "content": [{"type": "text", "text": "The weather in SF (San Francisco) is currently **20\\u00b0C** and **sunny**!"}], "stop_reason": "end_turn", "stop_sequence": null, "usage": {"input_tokens": 705, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 23, "service_tier": "standard"}}', - ] - ), - }, - "tool_call_error": { - "responses": snapshot( - [ - '{"model": "claude-haiku-4-5-20251001", "id": "msg_01QhmJFoA3mxD2mxPFnjLHrT", "type": "message", "role": "assistant", "content": [{"type": "tool_use", "id": "toolu_01Do4cDVNxt51EuosKoxdmii", "name": "get_weather", "input": {"location": "San Francisco, CA", "units": "f"}}], "stop_reason": "tool_use", "stop_sequence": null, "usage": {"input_tokens": 656, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 74, "service_tier": "standard"}}', - '{"model": "claude-haiku-4-5-20251001", "id": "msg_0137FupJYD4A3Mc6jUUxKpU6", "type": "message", "role": "assistant", "content": [{"type": "text", "text": "I apologize, but I encountered an error when trying to fetch the weather for San Francisco. This appears to be a temporary issue with the weather service. Could you please try again in a moment, or let me know if you\'d like me to attempt the lookup again?"}], "stop_reason": "end_turn", "stop_sequence": null, "usage": {"input_tokens": 760, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 58, "service_tier": "standard"}}', - ] - ) - }, -} +# `./scripts/test --inline-snapshot=fix -n0 --http-record` @pytest.mark.skipif(PYDANTIC_V1, reason="tool runner not supported with pydantic v1") class TestSyncRunTools: - @pytest.mark.respx(base_url=base_url) - def test_basic_call_sync(self, client: Anthropic, respx_mock: MockRouter, monkeypatch: pytest.MonkeyPatch) -> None: + @pytest.mark.parametrize( + "http_snapshot", + [cast(Any, external("uuid:ad005e89-f72b-4f0e-941a-9ec3473c1bc8.json"))], + ) + def test_basic_call_sync(self, snapshot_client: Anthropic) -> None: @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit @@ -91,27 +43,54 @@ def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResu """ return json.dumps(_get_weather(location, units)) - message = make_snapshot_request( - lambda c: c.beta.messages.tool_runner( - max_tokens=1024, - model="claude-haiku-4-5", - tools=[get_weather], - messages=[{"role": "user", "content": "What is the weather in SF?"}], - ).until_done(), - content_snapshot=snapshots["basic"]["responses"], - path="/v1/messages", - mock_client=client, - respx_mock=respx_mock, + message = snapshot_client.beta.messages.tool_runner( + max_tokens=1024, + model="claude-haiku-4-5", + tools=[get_weather], + messages=[{"role": "user", "content": "What is the weather in SF?"}], + ).until_done() + + assert print_obj(message) == snapshot( + """\ +ParsedBetaMessage( + container=None, + content=[ + ParsedBetaTextBlock( + citations=None, + parsed_output=None, + text='The weather in San Francisco is currently **68°F and Sunny**. Great day to be out and about!', + type='text' + ) + ], + context_management=None, + id='msg_01FvTMNojoLmBYw4KxJXB27y', + model='claude-haiku-4-5-20251001', + role='assistant', + stop_reason='end_turn', + stop_sequence=None, + type='message', + usage=BetaUsage( + cache_creation=BetaCacheCreation(ephemeral_1h_input_tokens=0, ephemeral_5m_input_tokens=0), + cache_creation_input_tokens=0, + cache_read_input_tokens=0, + input_tokens=770, + output_tokens=27, + server_tool_use=None, + service_tier='standard' + ) +) +""" ) - assert print_obj(message, monkeypatch) == snapshots["basic"]["result"] - - @pytest.mark.respx(base_url=base_url) + @pytest.mark.parametrize( + "http_snapshot", + [ + cast(Any, external("uuid:6cd089e9-1c08-40a5-851d-c272b3f1c248.json")), + ], + ) def test_tool_call_error( self, - client: Anthropic, - respx_mock: MockRouter, - monkeypatch: pytest.MonkeyPatch, + snapshot_client: Anthropic, caplog: pytest.LogCaptureFixture, ) -> None: called = None @@ -136,7 +115,7 @@ def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResu def tool_runner(client: Anthropic) -> List[Union[BetaMessageParam, None]]: runner = client.beta.messages.tool_runner( max_tokens=1024, - model="claude-haiku-4-5", + model="claude-3-5-haiku-latest", tools=[get_weather], messages=[{"role": "user", "content": "What is the weather in SF?"}], ) @@ -150,14 +129,7 @@ def tool_runner(client: Anthropic) -> List[Union[BetaMessageParam, None]]: return actual_responses with caplog.at_level(logging.ERROR): - message = make_snapshot_request( - tool_runner, - content_snapshot=snapshots["tool_call_error"]["responses"], - path="/v1/messages", - mock_client=client, - respx_mock=respx_mock, - ) - + message = tool_runner(snapshot_client) assert caplog.record_tuples == [ ( "anthropic.lib.tools._beta_runner", @@ -165,14 +137,39 @@ def tool_runner(client: Anthropic) -> List[Union[BetaMessageParam, None]]: "Error occurred while calling tool: get_weather", ), ] - assert print_obj(message, monkeypatch) == snapshot( - "[{'role': 'user', 'content': [{'type': 'tool_result', 'tool_use_id': 'toolu_01Do4cDVNxt51EuosKoxdmii', 'content': \"RuntimeError('Unexpected error, try again')\", 'is_error': True}]}]\n" + assert print_obj(message) == snapshot( + """\ +[ + { + 'role': 'user', + 'content': [ + { + 'type': 'tool_result', + 'tool_use_id': 'toolu_01Not8sU7rvvvixVRigDz1ee', + 'content': "RuntimeError('Unexpected error, try again')", + 'is_error': True + } + ] + }, + { + 'role': 'user', + 'content': [ + { + 'type': 'tool_result', + 'tool_use_id': 'toolu_01LJTxn5gThzGiq5MgRfbogp', + 'content': '{"location": "San Francisco, CA", "temperature": "68\\\\u00b0F", "condition": "Sunny"}' + } + ] + } +] +""" ) - @pytest.mark.respx(base_url=base_url) - def test_custom_message_handling( - self, client: Anthropic, respx_mock: MockRouter, monkeypatch: pytest.MonkeyPatch - ) -> None: + @pytest.mark.parametrize( + "http_snapshot", + [cast(Any, external("uuid:f1c3350a-cdb1-4508-a208-18544b825a9e.json"))], + ) + def test_custom_message_handling(self, snapshot_client: Anthropic) -> None: @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit @@ -197,8 +194,9 @@ def custom_message_handling(client: Anthropic) -> BetaMessage: # handle only where there is a tool call if message.content[0].type == "tool_use": runner.append_messages( + message, BetaMessageParam( - role="assistant", + role="user", content=[ BetaToolResultBlockParam( tool_use_id=message.content[0].id, @@ -211,18 +209,47 @@ def custom_message_handling(client: Anthropic) -> BetaMessage: return runner.until_done() - message = make_snapshot_request( - custom_message_handling, - content_snapshot=snapshots["custom"]["responses"], - path="/v1/messages", - mock_client=client, - respx_mock=respx_mock, + message = custom_message_handling(snapshot_client) + assert print_obj(message) == snapshot( + """\ +ParsedBetaMessage( + container=None, + content=[ + ParsedBetaTextBlock( + citations=None, + parsed_output=None, + text='The weather in San Francisco, CA is currently **sunny** with a temperature of **20°C**.', + type='text' + ) + ], + context_management=None, + id='msg_01K4waJ1jAaJvWS9uatX5ANU', + model='claude-haiku-4-5-20251001', + role='assistant', + stop_reason='end_turn', + stop_sequence=None, + type='message', + usage=BetaUsage( + cache_creation=BetaCacheCreation(ephemeral_1h_input_tokens=0, ephemeral_5m_input_tokens=0), + cache_creation_input_tokens=0, + cache_read_input_tokens=0, + input_tokens=763, + output_tokens=24, + server_tool_use=None, + service_tier='standard' + ) +) +""" ) - assert print_obj(message, monkeypatch) == snapshots["custom"]["result"] - - @pytest.mark.respx(base_url=base_url) - def test_tool_call_caching(self, client: Anthropic, respx_mock: MockRouter) -> None: + @pytest.mark.parametrize( + "http_snapshot", + [cast(Any, external("uuid:6401445a-5758-4777-9778-3008bae873ec.json"))], + ) + def test_tool_call_caching( + self, + snapshot_client: Anthropic, + ) -> None: called = None @beta_tool @@ -256,18 +283,13 @@ def tool_runner(client: Anthropic) -> None: if response1 is not None: assert response1 is response2 - make_snapshot_request( - tool_runner, - content_snapshot=snapshots["tool_call"]["responses"], - path="/v1/messages", - mock_client=client, - respx_mock=respx_mock, - ) + tool_runner(snapshot_client) - @pytest.mark.respx(base_url=base_url) - def test_streaming_call_sync( - self, client: Anthropic, respx_mock: MockRouter, monkeypatch: pytest.MonkeyPatch - ) -> None: + @pytest.mark.parametrize( + "http_snapshot", + [cast(Any, external("uuid:ff848716-2309-477f-8e90-39877809aaad.json"))], + ) + def test_streaming_call_sync(self, snapshot_client: Anthropic) -> None: @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit @@ -280,24 +302,55 @@ def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResu """ return json.dumps(_get_weather(location, units)) - last_response_messsage = make_stream_snapshot_request( - lambda c: c.beta.messages.tool_runner( + last_response_messsage = ( + snapshot_client.beta.messages.tool_runner( max_tokens=1024, model="claude-haiku-4-5", tools=[get_weather], messages=[{"role": "user", "content": "What is the weather in SF?"}], stream=True, ).until_done(), - content_snapshot=external("hash:cd8d3d185e7a*.json"), - path="/v1/messages", - mock_client=client, - respx_mock=respx_mock, ) - assert print_obj(last_response_messsage, monkeypatch) == snapshots["streaming"]["result"] + assert print_obj(last_response_messsage) == snapshot( + """\ +( + ParsedBetaMessage( + container=None, + content=[ + ParsedBetaTextBlock( + citations=None, + parsed_output=None, + text='The weather in San Francisco, CA is currently **68°F and Sunny** ☀️', + type='text' + ) + ], + context_management=None, + id='msg_01ERB2ekevEhTbZtAuM2HjmS', + model='claude-haiku-4-5-20251001', + role='assistant', + stop_reason='end_turn', + stop_sequence=None, + type='message', + usage=BetaUsage( + cache_creation=BetaCacheCreation(ephemeral_1h_input_tokens=0, ephemeral_5m_input_tokens=0), + cache_creation_input_tokens=0, + cache_read_input_tokens=0, + input_tokens=770, + output_tokens=24, + server_tool_use=None, + service_tier='standard' + ) + ), +) +""" + ) - @pytest.mark.respx(base_url=base_url) - def test_max_iterations(self, client: Anthropic, respx_mock: MockRouter, monkeypatch: pytest.MonkeyPatch) -> None: + @pytest.mark.parametrize( + "http_snapshot", + [cast(Any, external("uuid:4a71c9f9-6191-4820-b1a1-89f3bb179078.json"))], + ) + def test_max_iterations(self, snapshot_client: Anthropic) -> None: @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit @@ -335,25 +388,43 @@ def get_weather_answers(client: Anthropic) -> List[Union[BetaMessageParam, None] return answers - answers = make_snapshot_request( - get_weather_answers, - content_snapshot=snapshot( - [ - '{"model": "claude-haiku-4-5-20251001", "id": "msg_017GvdrboNn8hipoMJUcK8m6", "type": "message", "role": "assistant", "content": [{"type": "text", "text": "I\'ll get the weather for each of these cities one at a time. Let me start with San Francisco."}, {"type": "tool_use", "id": "toolu_011Q6hjHnpWegJvV1Zn6Cm1h", "name": "get_weather", "input": {"location": "San Francisco, CA", "units": "f"}}], "stop_reason": "tool_use", "stop_sequence": null, "usage": {"input_tokens": 701, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 96, "service_tier": "standard"}}', - '{"model": "claude-haiku-4-5-20251001", "id": "msg_01PYFQH4AkK3NBgSpFkWD16q", "type": "message", "role": "assistant", "content": [{"type": "text", "text": "Now let me check New York."}, {"type": "tool_use", "id": "toolu_011QaaAuMeNWTwHjkxcxce1D", "name": "get_weather", "input": {"location": "New York, NY", "units": "f"}}], "stop_reason": "tool_use", "stop_sequence": null, "usage": {"input_tokens": 837, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": {"ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0}, "output_tokens": 81, "service_tier": "standard"}}', - ] - ), - path="/v1/messages", - mock_client=client, - respx_mock=respx_mock, - ) + answers = get_weather_answers(snapshot_client) - assert print_obj(answers, monkeypatch) == snapshot( - "[{'role': 'user', 'content': [{'type': 'tool_result', 'tool_use_id': 'toolu_011Q6hjHnpWegJvV1Zn6Cm1h', 'content': '{\"location\": \"San Francisco, CA\", \"temperature\": \"68\\\\u00b0F\", \"condition\": \"Sunny\"}'}]}, {'role': 'user', 'content': [{'type': 'tool_result', 'tool_use_id': 'toolu_011QaaAuMeNWTwHjkxcxce1D', 'content': '{\"location\": \"New York, NY\", \"temperature\": \"68\\\\u00b0F\", \"condition\": \"Sunny\"}'}]}]\n" + assert print_obj(answers) == snapshot( + """\ +[ + { + 'role': 'user', + 'content': [ + { + 'type': 'tool_result', + 'tool_use_id': 'toolu_01FpmqujJtkj11RDCJySJWUH', + 'content': '{"location": "San Francisco, CA", "temperature": "68\\\\u00b0F", "condition": "Sunny"}' + } + ] + }, + { + 'role': 'user', + 'content': [ + { + 'type': 'tool_result', + 'tool_use_id': 'toolu_017cDHUBfAhBDseR2vW7axod', + 'content': '{"location": "New York, NY", "temperature": "68\\\\u00b0F", "condition": "Sunny"}' + } + ] + } +] +""" ) - @pytest.mark.respx(base_url=base_url) - def test_streaming_call_sync_events(self, client: Anthropic, respx_mock: MockRouter) -> None: + @pytest.mark.parametrize( + "http_snapshot", + [cast(Any, external("uuid:f27add0c-5771-4452-8ed9-996f5d74ef77.json"))], + ) + def test_streaming_call_sync_events( + self, + snapshot_client: Anthropic, + ) -> None: @beta_tool def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: """Lookup the weather for a given city in either celsius or fahrenheit @@ -381,13 +452,7 @@ def accumulate_events(client: Anthropic) -> List[str]: events.append(event.type) return events - events = make_stream_snapshot_request( - accumulate_events, - content_snapshot=external("uuid:9cb114c8-69bd-4111-841b-edee30333afd.json"), - path="/v1/messages", - mock_client=client, - respx_mock=respx_mock, - ) + events = accumulate_events(snapshot_client) assert set(events) == snapshot( { "content_block_delta", @@ -401,10 +466,11 @@ def accumulate_events(client: Anthropic) -> List[str]: } ) - @pytest.mark.respx(base_url=base_url) - def test_compaction_control( - self, client: Anthropic, respx_mock: MockRouter, caplog: pytest.LogCaptureFixture - ) -> None: + @pytest.mark.parametrize( + "http_snapshot", + [cast(Any, external("uuid:e4c374b8-ae08-48f3-96e5-9d28066820b0.json"))], + ) + def test_compaction_control(self, snapshot_client: Anthropic, caplog: pytest.LogCaptureFixture) -> None: @beta_tool def submit_analysis(summary: str) -> str: # noqa: ARG001 """Call this LAST with your final analysis.""" @@ -435,13 +501,7 @@ def tool_runner(client: Anthropic) -> BetaToolRunner[None]: return runner with caplog.at_level(logging.INFO, logger="anthropic.lib.tools._beta_runner"): - runner = make_snapshot_request( - tool_runner, - content_snapshot=external("uuid:ab7b2edd-9c2d-4f53-9c04-92bb659b9caa.json"), - path="/v1/messages", - mock_client=client, - respx_mock=respx_mock, - ) + runner = tool_runner(snapshot_client) messages = list(runner._params["messages"]) assert len(messages) == 1 @@ -453,50 +513,57 @@ def tool_runner(client: Anthropic) -> BetaToolRunner[None]: assert content["text"] == snapshot("""\ ## 1. Task Overview -The user requests a 500-word essay about dogs, cats, and birds, followed by a single call to the `submit_analysis` tool at the end containing information about all three animals. \n\ +The user has requested: +- Write a detailed 500-word essay about dogs, cats, and birds +- Call the tool `submit_analysis` ONCE at the end with information about all three animals +- The tool should contain compiled information from the essay about all three animal types -**Key constraints:** -- Essay must be detailed and approximately 500 words -- Must cover all three animals: dogs, cats, and birds -- Tool `submit_analysis` must be called exactly once, at the end -- Tool call should contain information about all three animals +Success criteria: +- Essay must be approximately 500 words +- Must cover all three animals (dogs, cats, birds) +- Must be detailed +- Single tool call at the very end containing analysis/information about all three animals ## 2. Current State **Completed:** Nothing has been completed yet. -**Status:** The task has been acknowledged but no essay has been written and no tool has been called. +**Files/Outputs:** None created. -**Artifacts produced:** None yet. +**Status:** Task not started. No essay has been written, and no tool has been called. ## 3. Important Discoveries -**Technical requirements:** -- Need to understand the parameters/schema for `submit_analysis` tool (not yet verified) -- Must structure the tool call to include data about all three animal types in a single invocation +No technical constraints have been uncovered yet, as work hasn't begun. -**Approach to take:** -- Write a comprehensive 500-word essay discussing dogs, cats, and birds -- Essay should cover characteristics, behaviors, and comparisons between the three -- Extract/organize key information about each animal for the tool call -- Call `submit_analysis` once with consolidated data about all three animals +**Key requirements identified:** +- Need to understand the `submit_analysis` tool parameters (what fields it accepts) +- The tool call should synthesize information about all three animals from the essay +- Only ONE tool call should be made, despite covering three different animals ## 4. Next Steps +**Immediate actions required:** + 1. **Write the 500-word essay** covering: - - Dogs: characteristics, behavior, relationship with humans - - Cats: characteristics, behavior, relationship with humans - - Birds: characteristics, behavior, diversity - - Comparisons and contrasts between the three - \n\ -2. **Determine the schema for `submit_analysis` tool** - check what parameters it accepts and how to structure data about multiple animals + - Dogs (characteristics, behavior, role as pets, etc.) + - Cats (characteristics, behavior, role as pets, etc.) + - Birds (characteristics, behavior, role as pets, etc.) + - Ensure balanced coverage of all three animals + - Aim for approximately 500 words total + +2. **Call `submit_analysis` tool once** after completing the essay: + - Structure the tool call to include information about all three animals + - Likely format: summarize key points about each animal type + - May need to check tool schema to understand expected parameters -3. **Call `submit_analysis` once** with information about all three animals in the appropriate format +**Priority:** Write essay first, then make single tool call. -4. **Verify word count** is approximately 500 words +**Blockers/Questions:** \n\ +- Need to determine exact parameters for `submit_analysis` tool when ready to call it ## 5. Context to Preserve -- User emphasized calling the tool "only once at the end" -- Essay should be "detailed" - not superficial -- The tool call must encompass information about all three animals, not separate calls per animal -- This appears to be a test of following multi-step instructions precisely +- User specifically emphasized calling the tool "only once at the end" +- Essay should be "detailed" - aim for substantive content, not superficial +- All three animals must be covered adequately +- Word count target: approximately 500 words \ """) assert caplog.record_tuples == snapshot( @@ -504,54 +571,46 @@ def tool_runner(client: Anthropic) -> BetaToolRunner[None]: ( "anthropic.lib.tools._beta_runner", 20, - "Token usage 1615 has exceeded the threshold of 500. Performing compaction.", + "Token usage 1663 has exceeded the threshold of 500. Performing compaction.", ), - ("anthropic.lib.tools._beta_runner", 20, "Compaction complete. New token usage: 496"), + ("anthropic.lib.tools._beta_runner", 20, "Compaction complete. New token usage: 518"), ] ) - @pytest.mark.parametrize("client", [False], indirect=True) - @pytest.mark.respx(base_url=base_url) + @pytest.mark.parametrize("http_snapshot", [cast(Any, external("uuid:6f763c87-ecb6-4217-8f6f-32db8e84a6be.json"))]) def test_server_side_tool( self, - client: Anthropic, - respx_mock: MockRouter, + snapshot_client: Anthropic, ) -> None: - def tool_runner(client: Anthropic) -> BetaToolRunner[None]: - runner = client.beta.messages.tool_runner( - model="claude-haiku-4-5", - messages=[{"role": "user", "content": "What is the weather in SF?"}], - tools=[ - { - "type": "web_search_20250305", - "name": "web_search", - } - ], - max_tokens=1024, - ) - - message = next(runner) - - content_types = [content.type for content in message.content] + runner = snapshot_client.beta.messages.tool_runner( + model="claude-haiku-4-5", + messages=[{"role": "user", "content": "What is the weather in SF?"}], + tools=[ + { + "type": "web_search_20250305", + "name": "web_search", + } + ], + max_tokens=1024, + ) - assert "server_tool_use" in content_types - assert "web_search_tool_result" in content_types + message = next(runner) - return runner + content_types = [content.type for content in message.content] - make_snapshot_request( - tool_runner, - content_snapshot=external("uuid:a0a711eb-ee0e-4a42-88d6-5c7f83c0f25a.txt"), - path="/v1/messages", - mock_client=client, - respx_mock=respx_mock, - ) + assert "server_tool_use" in content_types + assert "web_search_tool_result" in content_types @pytest.mark.skipif(PYDANTIC_V1, reason="tool runner not supported with pydantic v1") -@pytest.mark.respx(base_url=base_url) +@pytest.mark.parametrize( + "http_snapshot", + [ + cast(Any, external("uuid:c4061e82-ea59-4756-9549-71a35da24499.json")), + ], +) async def test_basic_call_async( - async_client: AsyncAnthropic, respx_mock: MockRouter, monkeypatch: pytest.MonkeyPatch + async_snapshot_client: AsyncAnthropic, ) -> None: @beta_async_tool async def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResultType: @@ -565,20 +624,12 @@ async def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionTo """ return json.dumps(_get_weather(location, units)) - message = await make_async_snapshot_request( - lambda c: c.beta.messages.tool_runner( - max_tokens=1024, - model="claude-3-7", - tools=[get_weather], - messages=[{"role": "user", "content": "What is the weather in SF?"}], - ).until_done(), - content_snapshot=snapshots["basic"]["responses"], - path="/v1/messages", - mock_client=async_client, - respx_mock=respx_mock, - ) - - assert print_obj(message, monkeypatch) == snapshots["basic"]["result"] + await async_snapshot_client.beta.messages.tool_runner( + max_tokens=1024, + model="claude-haiku-4-5", + tools=[get_weather], + messages=[{"role": "user", "content": "What is the weather in SF?"}], + ).until_done() def _get_weather(location: str, units: Literal["c", "f"]) -> Dict[str, Any]: diff --git a/tests/lib/utils.py b/tests/lib/utils.py index d6093dd3..c7685a03 100644 --- a/tests/lib/utils.py +++ b/tests/lib/utils.py @@ -1,6 +1,7 @@ from __future__ import annotations import io +import re import inspect from typing import Any, Iterable from typing_extensions import TypeAlias @@ -8,11 +9,13 @@ import rich import pytest import pydantic +import rich.pretty +import rich.console ReprArgs: TypeAlias = "Iterable[tuple[str | None, Any]]" -def print_obj(obj: object, monkeypatch: pytest.MonkeyPatch) -> str: +def print_obj(obj: object) -> str: """Pretty print an object to a string""" # monkeypatch pydantic model printing so that model fields @@ -28,7 +31,7 @@ def __repr_name__(self: pydantic.BaseModel) -> str: # e.g. `GenericModel[Location]` -> `GenericModel` return self.__class__.__name__.split("[", maxsplit=1)[0] - with monkeypatch.context() as m: + with pytest.MonkeyPatch.context() as m: m.setattr(pydantic.BaseModel, "__repr_args__", __repr_args__) m.setattr(pydantic.BaseModel, "__repr_name__", __repr_name__) @@ -61,10 +64,22 @@ def clear_locals(string: str, *, stacklevel: int) -> str: def rich_print_str(obj: object) -> str: - """Like `rich.print()` but returns the string instead""" - buf = io.StringIO() - - console = rich.console.Console(file=buf, width=120) - console.out(obj) + """Like `rich.print()` but returns a plain multi-line string (no ANSI codes).""" - return buf.getvalue() + buf = io.StringIO() + console = rich.console.Console( + file=buf, + width=120, + force_terminal=False, # disable terminal ANSI codes + color_system=None, # disable colors + record=True, + ) + + # Use Rich's pretty printer for nice multi-line formatting + rich.pretty.install(console) + console.print(obj, overflow="fold", width=120) + + result = buf.getvalue() + # Strip out [~...] patterns to exclude generic content from snapshots + result = re.sub(r"\[~[^\]]*\]", "", result) + return result diff --git a/uv.lock b/uv.lock index f2064b8c..47ab6a82 100644 --- a/uv.lock +++ b/uv.lock @@ -216,8 +216,7 @@ vertex = [ dev = [ { name = "boto3-stubs" }, { name = "dirty-equals" }, - { name = "griffe", version = "1.14.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, - { name = "griffe", version = "1.15.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, + { name = "http-snapshot", extra = ["httpx"] }, { name = "importlib-metadata" }, { name = "inline-snapshot" }, { name = "mypy" }, @@ -263,6 +262,7 @@ dev = [ { name = "boto3-stubs", specifier = ">=1" }, { name = "dirty-equals", specifier = ">=0.6.0" }, { name = "griffe", specifier = ">=1" }, + { name = "http-snapshot", extras = ["httpx"], specifier = "==0.1.4" }, { name = "importlib-metadata", specifier = ">=6.7.0" }, { name = "inline-snapshot", specifier = ">=0.28.0" }, { name = "mypy", specifier = "==1.17" }, @@ -773,6 +773,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, ] +[[package]] +name = "http-snapshot" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "inline-snapshot" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/97/5f/8fc01489d3857642c801a4598aa47a64a3ddb4e4b397b8ba0ead9e1eb6ca/http_snapshot-0.1.4.tar.gz", hash = "sha256:e51d021e82e61eaacda15448fb58f98e088480de428cc13dd77049760f12c969", size = 10752, upload-time = "2025-12-03T13:36:02.79Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/a8/c1552b6758d0991b547b6a691408282374f86dea441f82b40a7cf8e13dfa/http_snapshot-0.1.4-py3-none-any.whl", hash = "sha256:ee642c5ff36a01bdfe525c125786584ea3fe26f952a44022648db2d6ff03a845", size = 11429, upload-time = "2025-12-03T13:36:01.527Z" }, +] + +[package.optional-dependencies] +httpx = [ + { name = "httpx" }, +] + [[package]] name = "httpcore" version = "1.0.9" From b987a0b50b222641458cc1df28089a88c7ee6895 Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Fri, 5 Dec 2025 19:14:38 +0400 Subject: [PATCH 2/8] minor fixes --- CONTRIBUTING.md | 2 +- tests/lib/utils.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 84871033..b401785e 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -109,7 +109,7 @@ Some tests use [inline-snapshot](https://15r10nk.github.io/inline-snapshot/lates In addition, some tests capture snapshots of the HTTP requests they make. To refresh these snapshots, run the tests with the `--http-record` flag: ```bash -./scripts/test --inline-snapshot=fix --http-record +./scripts/test --inline-snapshot=fix --http-record -n0 ``` > [!NOTE] diff --git a/tests/lib/utils.py b/tests/lib/utils.py index c7685a03..d2be01bd 100644 --- a/tests/lib/utils.py +++ b/tests/lib/utils.py @@ -64,14 +64,14 @@ def clear_locals(string: str, *, stacklevel: int) -> str: def rich_print_str(obj: object) -> str: - """Like `rich.print()` but returns a plain multi-line string (no ANSI codes).""" + """Like `rich.print()` but returns the string instead""" buf = io.StringIO() console = rich.console.Console( file=buf, width=120, - force_terminal=False, # disable terminal ANSI codes - color_system=None, # disable colors + force_terminal=False, + color_system=None, record=True, ) From 813cf7979a1e9e8fd7dc598cb31e85658eabd10c Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Fri, 5 Dec 2025 19:16:17 +0400 Subject: [PATCH 3/8] minor fix --- tests/lib/_parse/test_beta_messages.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/lib/_parse/test_beta_messages.py b/tests/lib/_parse/test_beta_messages.py index ccfd8c4d..aa24cab4 100644 --- a/tests/lib/_parse/test_beta_messages.py +++ b/tests/lib/_parse/test_beta_messages.py @@ -39,4 +39,4 @@ async def async_stream_parse(client: AsyncAnthropic) -> ParsedBetaMessage[None]: response = await async_stream_parse(async_snapshot_client) - assert response.content[0].text == snapshot("[12345,67890]") + assert response.content[0].text == snapshot("[12345,67890]") # type: ignore From 2e8c04939d06cfa3d989f13c369b55221799bc5a Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Fri, 5 Dec 2025 19:27:34 +0400 Subject: [PATCH 4/8] fix lockfile --- uv.lock | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/uv.lock b/uv.lock index 47ab6a82..9db1ddfe 100644 --- a/uv.lock +++ b/uv.lock @@ -216,6 +216,7 @@ vertex = [ dev = [ { name = "boto3-stubs" }, { name = "dirty-equals" }, + { name = "griffe" }, { name = "http-snapshot", extra = ["httpx"] }, { name = "importlib-metadata" }, { name = "inline-snapshot" }, @@ -731,21 +732,6 @@ requests = [ { name = "requests" }, ] -[[package]] -name = "griffe" -version = "1.14.0" -source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version < '3.10'", -] -dependencies = [ - { name = "colorama", marker = "python_full_version < '3.10' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ec/d7/6c09dd7ce4c7837e4cdb11dce980cb45ae3cd87677298dc3b781b6bce7d3/griffe-1.14.0.tar.gz", hash = "sha256:9d2a15c1eca966d68e00517de5d69dd1bc5c9f2335ef6c1775362ba5b8651a13", size = 424684, upload-time = "2025-09-05T15:02:29.167Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2a/b1/9ff6578d789a89812ff21e4e0f80ffae20a65d5dd84e7a17873fe3b365be/griffe-1.14.0-py3-none-any.whl", hash = "sha256:0e9d52832cccf0f7188cfe585ba962d2674b241c01916d780925df34873bceb0", size = 144439, upload-time = "2025-09-05T15:02:27.511Z" }, -] - [[package]] name = "griffe" version = "1.15.0" From 5011e12d2f5059ecc6d00a99578097cd3dccd044 Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Fri, 5 Dec 2025 19:31:25 +0400 Subject: [PATCH 5/8] fix griffe --- uv.lock | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/uv.lock b/uv.lock index 9db1ddfe..879b4eed 100644 --- a/uv.lock +++ b/uv.lock @@ -734,20 +734,14 @@ requests = [ [[package]] name = "griffe" -version = "1.15.0" +version = "1.13.0" source = { registry = "https://pypi.org/simple" } -resolution-markers = [ - "python_full_version >= '3.14' and extra != 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2'", - "python_full_version >= '3.10' and python_full_version < '3.14' and extra != 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2'", - "python_full_version >= '3.10' and extra == 'group-9-anthropic-pydantic-v1' and extra != 'group-9-anthropic-pydantic-v2'", - "python_full_version >= '3.10' and extra != 'group-9-anthropic-pydantic-v1' and extra != 'group-9-anthropic-pydantic-v2'", -] dependencies = [ - { name = "colorama", marker = "python_full_version >= '3.10' or (extra == 'group-9-anthropic-pydantic-v1' and extra == 'group-9-anthropic-pydantic-v2')" }, + { name = "colorama" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/0d/0c/3a471b6e31951dce2360477420d0a8d1e00dea6cf33b70f3e8c3ab6e28e1/griffe-1.15.0.tar.gz", hash = "sha256:7726e3afd6f298fbc3696e67958803e7ac843c1cfe59734b6251a40cdbfb5eea", size = 424112, upload-time = "2025-11-10T15:03:15.52Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c6/b5/23b91f22b7b3a7f8f62223f6664946271c0f5cb4179605a3e6bbae863920/griffe-1.13.0.tar.gz", hash = "sha256:246ea436a5e78f7fbf5f24ca8a727bb4d2a4b442a2959052eea3d0bfe9a076e0", size = 412759, upload-time = "2025-08-26T13:27:11.422Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/9c/83/3b1d03d36f224edded98e9affd0467630fc09d766c0e56fb1498cbb04a9b/griffe-1.15.0-py3-none-any.whl", hash = "sha256:6f6762661949411031f5fcda9593f586e6ce8340f0ba88921a0f2ef7a81eb9a3", size = 150705, upload-time = "2025-11-10T15:03:13.549Z" }, + { url = "https://files.pythonhosted.org/packages/aa/8c/b7cfdd8dfe48f6b09f7353323732e1a290c388bd14f216947928dc85f904/griffe-1.13.0-py3-none-any.whl", hash = "sha256:470fde5b735625ac0a36296cd194617f039e9e83e301fcbd493e2b58382d0559", size = 139365, upload-time = "2025-08-26T13:27:09.882Z" }, ] [[package]] From 68202af2b02d660ebede3420ba1bd390595a152f Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Fri, 5 Dec 2025 19:36:54 +0400 Subject: [PATCH 6/8] remove new typevars from the snapshots --- tests/lib/utils.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/lib/utils.py b/tests/lib/utils.py index d2be01bd..4b61198d 100644 --- a/tests/lib/utils.py +++ b/tests/lib/utils.py @@ -82,4 +82,5 @@ def rich_print_str(obj: object) -> str: result = buf.getvalue() # Strip out [~...] patterns to exclude generic content from snapshots result = re.sub(r"\[~[^\]]*\]", "", result) + result = result.replace("[TypeVar]", "") return result From 9f97d6cac05b01f04f6a9515638a6d233a439de0 Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Tue, 16 Dec 2025 14:04:40 +0400 Subject: [PATCH 7/8] include request data in a snapshot, exclude some headers --- pyproject.toml | 2 +- tests/conftest.py | 27 +- .../606342ef-f614-4bc1-b5e7-2c3305a48bf3.json | 61 +- .../4a71c9f9-6191-4820-b1a1-89f3bb179078.json | 196 ++++++- .../6401445a-5758-4777-9778-3008bae873ec.json | 178 +++++- .../6cd089e9-1c08-40a5-851d-c272b3f1c248.json | 537 ++++++++++++++++-- .../6f763c87-ecb6-4217-8f6f-32db8e84a6be.json | 182 +++--- .../ad005e89-f72b-4f0e-941a-9ec3473c1bc8.json | 184 +++++- .../e4c374b8-ae08-48f3-96e5-9d28066820b0.json | 130 ++++- .../f1c3350a-cdb1-4508-a208-18544b825a9e.json | 186 +++++- .../f27add0c-5771-4452-8ed9-996f5d74ef77.json | 188 +++++- .../ff848716-2309-477f-8e90-39877809aaad.json | 188 +++++- .../c4061e82-ea59-4756-9549-71a35da24499.json | 186 +++++- tests/lib/tools/test_runners.py | 101 ++-- uv.lock | 8 +- 15 files changed, 2030 insertions(+), 324 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index bfe7fdf4..ba8d5c0d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dev = [ "pytest-xdist>=3.6.1", "inline-snapshot>=0.28.0", "griffe>=1", - "http-snapshot[httpx]==0.1.4", + "http-snapshot[httpx]==0.1.5", ] pydantic-v1 = [ "pydantic>=1.9.0,<2", diff --git a/tests/conftest.py b/tests/conftest.py index 62f0c002..0a9152d1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -8,6 +8,7 @@ import httpx import pytest +from http_snapshot import SnapshotSerializerOptions from pytest_asyncio import is_async_test from anthropic import Anthropic, AsyncAnthropic, DefaultAioHttpClient @@ -20,6 +21,18 @@ logging.getLogger("anthropic").setLevel(logging.DEBUG) +SNAPSHOT_RESPONSE_HEADERS_EXCLUDE = [ + "date", + "request-id", + "anthropic-organization-id", + "x-envoy-upstream-service-time", + "cf-ray", +] + +SNAPSHOT_REQUEST_HEADERS_EXCLUDE = [ + "x-api-key", +] + # automatically add `pytest.mark.asyncio()` to all of our async tests # so we don't have to add that boilerplate everywhere @@ -58,8 +71,20 @@ def client(request: FixtureRequest) -> Iterator[Anthropic]: yield client +@pytest.fixture +def http_snapshot_serializer_options() -> SnapshotSerializerOptions: + return SnapshotSerializerOptions( + exclude_response_headers=SNAPSHOT_RESPONSE_HEADERS_EXCLUDE, + exclude_request_headers=SNAPSHOT_REQUEST_HEADERS_EXCLUDE, + include_request=True, + ) + + @pytest.fixture(scope="function") -def snapshot_client(snapshot_sync_httpx_client: httpx.Client, is_recording: bool) -> Iterator[Anthropic]: +def snapshot_client( + snapshot_sync_httpx_client: httpx.Client, + is_recording: bool, +) -> Iterator[Anthropic]: with Anthropic(http_client=snapshot_sync_httpx_client, api_key=None if is_recording else api_key) as client: yield client diff --git a/tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages/606342ef-f614-4bc1-b5e7-2c3305a48bf3.json b/tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages/606342ef-f614-4bc1-b5e7-2c3305a48bf3.json index ea5ddbb6..c1f977e2 100644 --- a/tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages/606342ef-f614-4bc1-b5e7-2c3305a48bf3.json +++ b/tests/lib/_parse/__inline_snapshot__/test_beta_messages/TestAsyncMessages/606342ef-f614-4bc1-b5e7-2c3305a48bf3.json @@ -1,22 +1,65 @@ [ { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "NOT_GIVEN", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "AsyncAnthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "async:asyncio", + "anthropic-version": "2023-06-01", + "x-stainless-helper-method": "stream", + "x-stainless-stream-helper": "beta.messages", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "265" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "Extract order IDs from the following text:\n\nOrder 12345\nOrder 67890" + } + ], + "model": "claude-sonnet-4-5", + "output_format": { + "type": "json_schema", + "schema": { + "type": "array", + "items": { + "type": "integer" + } + } + }, + "stream": true + } + }, "response": { "status_code": 200, "headers": { - "date": "Fri, 05 Dec 2025 15:06:08 GMT", "content-type": "text/event-stream; charset=utf-8", "connection": "keep-alive", - "cf-ray": "9a947204ac019fb2-AMS", + "server": "cloudflare", + "cf-cache-status": "DYNAMIC", "cache-control": "no-cache", - "request-id": "req_011CVokJu9sXWCZuA7nVS1g3", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "3888", - "cf-cache-status": "DYNAMIC", - "x-robots-tag": "none", - "server": "cloudflare" + "vary": "Accept-Encoding", + "x-robots-tag": "none" }, - "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_015jm362jgYXWyFRvq8NHxPr\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":135,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"[\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"12\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"345,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"67890]\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":135,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":10} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" + "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01JbzU4eQy8GBAU9N2KuLT93\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":135,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"[\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"12\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"345,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"67890]\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":135,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":10} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" } } ] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/4a71c9f9-6191-4820-b1a1-89f3bb179078.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/4a71c9f9-6191-4820-b1a1-89f3bb179078.json index 1b7c28ab..65ce115c 100644 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/4a71c9f9-6191-4820-b1a1-89f3bb179078.json +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/4a71c9f9-6191-4820-b1a1-89f3bb179078.json @@ -1,33 +1,95 @@ [ { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "781" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What's the weather in San Francisco, New York, London, Tokyo and Paris?If you need to use tools, call only one tool at a time. Wait for the tool’sresponse before making another call. Never call multiple tools at once." + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:38 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk7MF3CAWoGsJWoWtwSF", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1373", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a849d968f690bc0-AMS" + "server": "cloudflare" }, "body": { "model": "claude-haiku-4-5-20251001", - "id": "msg_01W4f7BbpEG9NWkq6hifE8si", + "id": "msg_01WazLBoVU9XD7M54uN8hcGD", "type": "message", "role": "assistant", "content": [ { "type": "text", - "text": "I'll get the weather for each of these cities one at a time. Let me start with San Francisco." + "text": "I'll get the weather for each of these cities. Let me start by checking San Francisco." }, { "type": "tool_use", - "id": "toolu_01FpmqujJtkj11RDCJySJWUH", + "id": "toolu_01DUC5sKZofEcuFX4NTvXAGp", "name": "get_weather", "input": { "location": "San Francisco, CA", @@ -45,41 +107,131 @@ "ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0 }, - "output_tokens": 96, + "output_tokens": 93, "service_tier": "standard" } } } }, { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "1265" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What's the weather in San Francisco, New York, London, Tokyo and Paris?If you need to use tools, call only one tool at a time. Wait for the tool’sresponse before making another call. Never call multiple tools at once." + }, + { + "role": "assistant", + "content": [ + { + "text": "I'll get the weather for each of these cities. Let me start by checking San Francisco.", + "type": "text" + }, + { + "id": "toolu_01DUC5sKZofEcuFX4NTvXAGp", + "input": { + "location": "San Francisco, CA", + "units": "f" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_01DUC5sKZofEcuFX4NTvXAGp", + "content": "{\"location\": \"San Francisco, CA\", \"temperature\": \"68\\u00b0F\", \"condition\": \"Sunny\"}" + } + ] + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:40 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk7MMiH2qTFqRNanpHUe", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1109", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a849da04ef60bc0-AMS" + "server": "cloudflare" }, "body": { "model": "claude-haiku-4-5-20251001", - "id": "msg_01NJyxkC7vtwSFZm4d3KJRUt", + "id": "msg_01QHdi3sMxCqoFkWw1UapVEw", "type": "message", "role": "assistant", "content": [ { "type": "text", - "text": "Now let me check New York:" + "text": "Now let me check New York." }, { "type": "tool_use", - "id": "toolu_017cDHUBfAhBDseR2vW7axod", + "id": "toolu_01B3V3NpBkEHenKXsgAW7mhQ", "name": "get_weather", "input": { "location": "New York, NY", @@ -90,7 +242,7 @@ "stop_reason": "tool_use", "stop_sequence": null, "usage": { - "input_tokens": 837, + "input_tokens": 834, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": { diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6401445a-5758-4777-9778-3008bae873ec.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6401445a-5758-4777-9778-3008bae873ec.json index 75a2174f..1c9597a7 100644 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6401445a-5758-4777-9778-3008bae873ec.json +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6401445a-5758-4777-9778-3008bae873ec.json @@ -1,29 +1,89 @@ [ { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "390" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What's the weather in SF in Celsius?" + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "title": "Location", + "type": "string" + }, + "units": { + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:32 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk7LmzVt3Z3yYKFxpWbn", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1315", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a849d6efcbe8c7a-AMS" + "server": "cloudflare" }, "body": { "model": "claude-haiku-4-5-20251001", - "id": "msg_01S4zx3T748n7ZVrLGAGfgFS", + "id": "msg_016LXp91BGtikmRAGAeGuddr", "type": "message", "role": "assistant", "content": [ { "type": "tool_use", - "id": "toolu_01LTJ5KhgNy2y3RoyfR4dgBk", + "id": "toolu_01Gioi16VivrVViPseH2cZDu", "name": "get_weather", "input": { "location": "SF", @@ -48,24 +108,108 @@ } }, { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "732" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What's the weather in SF in Celsius?" + }, + { + "role": "assistant", + "content": [ + { + "id": "toolu_01Gioi16VivrVViPseH2cZDu", + "input": { + "location": "SF", + "units": "c" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_01Gioi16VivrVViPseH2cZDu", + "content": "{\"location\": \"SF\", \"temperature\": \"20\\u00b0C\", \"condition\": \"Sunny\"}" + } + ] + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "title": "Location", + "type": "string" + }, + "units": { + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:33 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk7LtNydsBSrctuycfL6", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1013", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a849d785e5c8c7a-AMS" + "server": "cloudflare" }, "body": { "model": "claude-haiku-4-5-20251001", - "id": "msg_01JMXwhaAsHMreUdrfoNbQKs", + "id": "msg_018wBXcYwLjNFfcwWmQN1uGN", "type": "message", "role": "assistant", "content": [ diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6cd089e9-1c08-40a5-851d-c272b3f1c248.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6cd089e9-1c08-40a5-851d-c272b3f1c248.json index addb29c4..45bf821a 100644 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6cd089e9-1c08-40a5-851d-c272b3f1c248.json +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6cd089e9-1c08-40a5-851d-c272b3f1c248.json @@ -1,33 +1,95 @@ [ { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "595" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + } + ], + "model": "claude-3-5-haiku-latest", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:23 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk7L32bmhx4PN5W2e674", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "2019", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a849d30391fc13c-AMS" + "server": "cloudflare" }, "body": { "model": "claude-3-5-haiku-20241022", - "id": "msg_01DXhC71psJn1RhEsecTydUB", + "id": "msg_01275mRYhdQWbNVMxZjVzshJ", "type": "message", "role": "assistant", "content": [ { "type": "text", - "text": "I'll help you get the weather for San Francisco. I'll retrieve the temperature in Fahrenheit, which is typically preferred in the United States." + "text": "I'll help you get the weather for San Francisco. I'll retrieve the temperature in both Fahrenheit and Celsius for you." }, { "type": "tool_use", - "id": "toolu_01Not8sU7rvvvixVRigDz1ee", + "id": "toolu_01ASSujsMzFEe4PjhTGzbmdi", "name": "get_weather", "input": { "location": "San Francisco, CA", @@ -45,41 +107,132 @@ "ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0 }, - "output_tokens": 104, + "output_tokens": 101, "service_tier": "standard" } } } }, { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "1074" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + }, + { + "role": "assistant", + "content": [ + { + "text": "I'll help you get the weather for San Francisco. I'll retrieve the temperature in both Fahrenheit and Celsius for you.", + "type": "text" + }, + { + "id": "toolu_01ASSujsMzFEe4PjhTGzbmdi", + "input": { + "location": "San Francisco, CA", + "units": "f" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_01ASSujsMzFEe4PjhTGzbmdi", + "content": "RuntimeError('Unexpected error, try again')", + "is_error": true + } + ] + } + ], + "model": "claude-3-5-haiku-latest", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:25 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk7LCRQJ2cqN2vpz4veM", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "2148", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a849d3dffa9c13c-AMS" + "server": "cloudflare" }, "body": { "model": "claude-3-5-haiku-20241022", - "id": "msg_01WeMH1D2TYPZYj7Vbm2XVDN", + "id": "msg_01HFNsNvYNRazCCp9L6Ean9Y", "type": "message", "role": "assistant", "content": [ { "type": "text", - "text": "I apologize, but it seems there was an unexpected error when trying to retrieve the weather information. This can happen due to temporary system issues. Let me try again:" + "text": "I apologize, but there seems to be a temporary issue with retrieving the weather information. Let me try again:" }, { "type": "tool_use", - "id": "toolu_01LJTxn5gThzGiq5MgRfbogp", + "id": "toolu_01RPpGTPHZBTK27CruspxqvL", "name": "get_weather", "input": { "location": "San Francisco, CA", @@ -90,57 +243,375 @@ "stop_reason": "tool_use", "stop_sequence": null, "usage": { - "input_tokens": 557, + "input_tokens": 554, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": { "ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0 }, - "output_tokens": 109, + "output_tokens": 99, "service_tier": "standard" } } } }, { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "1583" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + }, + { + "role": "assistant", + "content": [ + { + "text": "I'll help you get the weather for San Francisco. I'll retrieve the temperature in both Fahrenheit and Celsius for you.", + "type": "text" + }, + { + "id": "toolu_01ASSujsMzFEe4PjhTGzbmdi", + "input": { + "location": "San Francisco, CA", + "units": "f" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_01ASSujsMzFEe4PjhTGzbmdi", + "content": "RuntimeError('Unexpected error, try again')", + "is_error": true + } + ] + }, + { + "role": "assistant", + "content": [ + { + "text": "I apologize, but there seems to be a temporary issue with retrieving the weather information. Let me try again:", + "type": "text" + }, + { + "id": "toolu_01RPpGTPHZBTK27CruspxqvL", + "input": { + "location": "San Francisco, CA", + "units": "f" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_01RPpGTPHZBTK27CruspxqvL", + "content": "{\"location\": \"San Francisco, CA\", \"temperature\": \"68\\u00b0F\", \"condition\": \"Sunny\"}" + } + ] + } + ], + "model": "claude-3-5-haiku-latest", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:27 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk7LNPBn1Qv62UVz8PSD", + "cf-cache-status": "DYNAMIC", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1650", + "vary": "Accept-Encoding", + "x-robots-tag": "none", + "server": "cloudflare" + }, + "body": { + "model": "claude-3-5-haiku-20241022", + "id": "msg_013dwJgYtm14xyz4VJ8J8gnA", + "type": "message", + "role": "assistant", + "content": [ + { + "type": "text", + "text": "Great! Here's the current weather in San Francisco:\n- Temperature: 68°F\n- Condition: Sunny\n\nLet me also get the temperature in Celsius for you:" + }, + { + "type": "tool_use", + "id": "toolu_014Qf7b4odsWZYj4ngf41v5R", + "name": "get_weather", + "input": { + "location": "San Francisco, CA", + "units": "c" + } + } + ], + "stop_reason": "tool_use", + "stop_sequence": null, + "usage": { + "input_tokens": 692, + "cache_creation_input_tokens": 0, + "cache_read_input_tokens": 0, + "cache_creation": { + "ephemeral_5m_input_tokens": 0, + "ephemeral_1h_input_tokens": 0 + }, + "output_tokens": 114, + "service_tier": "standard" + } + } + } + }, + { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "2129" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + }, + { + "role": "assistant", + "content": [ + { + "text": "I'll help you get the weather for San Francisco. I'll retrieve the temperature in both Fahrenheit and Celsius for you.", + "type": "text" + }, + { + "id": "toolu_01ASSujsMzFEe4PjhTGzbmdi", + "input": { + "location": "San Francisco, CA", + "units": "f" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_01ASSujsMzFEe4PjhTGzbmdi", + "content": "RuntimeError('Unexpected error, try again')", + "is_error": true + } + ] + }, + { + "role": "assistant", + "content": [ + { + "text": "I apologize, but there seems to be a temporary issue with retrieving the weather information. Let me try again:", + "type": "text" + }, + { + "id": "toolu_01RPpGTPHZBTK27CruspxqvL", + "input": { + "location": "San Francisco, CA", + "units": "f" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_01RPpGTPHZBTK27CruspxqvL", + "content": "{\"location\": \"San Francisco, CA\", \"temperature\": \"68\\u00b0F\", \"condition\": \"Sunny\"}" + } + ] + }, + { + "role": "assistant", + "content": [ + { + "text": "Great! Here's the current weather in San Francisco:\n- Temperature: 68°F\n- Condition: Sunny\n\nLet me also get the temperature in Celsius for you:", + "type": "text" + }, + { + "id": "toolu_014Qf7b4odsWZYj4ngf41v5R", + "input": { + "location": "San Francisco, CA", + "units": "c" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_014Qf7b4odsWZYj4ngf41v5R", + "content": "{\"location\": \"San Francisco, CA\", \"temperature\": \"20\\u00b0C\", \"condition\": \"Sunny\"}" + } + ] + } + ], + "model": "claude-3-5-haiku-latest", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, + "response": { + "status_code": 200, + "headers": { + "content-type": "application/json", + "connection": "keep-alive", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a849d4c7932c13c-AMS" + "server": "cloudflare" }, "body": { "model": "claude-3-5-haiku-20241022", - "id": "msg_01Pq1Tj1FV2uXN5mZm7sphQi", + "id": "msg_01BpDU7ntE7GTXZFUv9i4es7", "type": "message", "role": "assistant", "content": [ { "type": "text", - "text": "Great! Here's the current weather in San Francisco:\n- Temperature: 68°F\n- Condition: Sunny\n\nIt looks like a beautiful, mild day in San Francisco with sunny skies and a comfortable temperature of 68 degrees Fahrenheit." + "text": "- Temperature: 20°C\n\nIt's a beautiful sunny day in San Francisco!" } ], "stop_reason": "end_turn", "stop_sequence": null, "usage": { - "input_tokens": 705, + "input_tokens": 845, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": { "ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0 }, - "output_tokens": 59, + "output_tokens": 22, "service_tier": "standard" } } diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6f763c87-ecb6-4217-8f6f-32db8e84a6be.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6f763c87-ecb6-4217-8f6f-32db8e84a6be.json index eb24ec5f..7056cdd1 100644 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6f763c87-ecb6-4217-8f6f-32db8e84a6be.json +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/6f763c87-ecb6-4217-8f6f-32db8e84a6be.json @@ -1,177 +1,215 @@ [ { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "175" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "type": "web_search_20250305", + "name": "web_search" + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Fri, 05 Dec 2025 15:05:54 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVokHqKukgk86TgfHSWRn", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "3589", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a9471aa6f319a0e-AMS" + "server": "cloudflare" }, "body": { "model": "claude-haiku-4-5-20251001", - "id": "msg_01RAEMSsi4gkXbrnF8wr2FX5", + "id": "msg_01MGkxozBoPDqy5jbybFMJPb", "type": "message", "role": "assistant", "content": [ + { + "type": "text", + "text": "I'll search for the current weather in San Francisco for you." + }, { "type": "server_tool_use", - "id": "srvtoolu_01A3t4TfPKgiXf6nKDGsD3c1", + "id": "srvtoolu_01H4rAobZLG4aVty6fUuEqTk", "name": "web_search", "input": { - "query": "SF weather today" + "query": "San Francisco weather today" } }, { "type": "web_search_tool_result", - "tool_use_id": "srvtoolu_01A3t4TfPKgiXf6nKDGsD3c1", + "tool_use_id": "srvtoolu_01H4rAobZLG4aVty6fUuEqTk", "content": [ { "type": "web_search_result", "title": "San Francisco, CA Weather Forecast | AccuWeather", "url": "https://www.accuweather.com/en/us/san-francisco/94103/weather-forecast/347629", - "encrypted_content": "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", - "page_age": "3 days ago" + "encrypted_content": "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", + "page_age": "2 weeks ago" }, { "type": "web_search_result", - "title": "San Francisco, CA Hourly Weather Forecast | Weather Underground", - "url": "https://www.wunderground.com/hourly/us/ca/san-francisco", - "encrypted_content": "EtUNCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDAv+PJG4Ojr+WbF+6xoMwwuU4HjYXSM5IUWXIjD4ZUSAvuSXl9Hbg7onyxNsxbzRUjwltHGH4opke4I1CsOdmesh4fP3hXjnF1Ho73Yq2AwNeTfw3Akca+F/AhogB4Eh/HJg/a8hW70TCiEBDpvn4+IIt+BrQiNGLLAeF55+yyHKwwKc/TL1aH6/NiBf2y2+A6nHzfs09LOV+T3JcUk5ZN9UHdwiEaut+G3NarKmS26OLhMIQgqYQopbo++clrG2CpZHS357AKXuiXforjVBr4RI+phQkeXJ/JQpH4hl3OaZTMnlKWdgvfNQxfHk8SlvphniCAsSMJURxknSQsg0/hRSG5gaRbGkqaqBQb/rPFcQDVFiX95ib99GGNbiniwbgWuTtdm/4izrFzyolYS1SA3HwcVDvPuWMDC5EzwIOoPrVTANB5U4Uwy1p/zX/ZG+VPM4tFhDb4iAqESoAEVf9t/6vk2AOIMROzxd2/agJPhoLQY0IuzZYYFYO0jV/JMoUqDuohaIKwX0WLrT5QHMe8qcAnyhE+ncMKZjQhsMXhxg4EF5ICDa81Y6HDbRwPl2MYRHtg2B0aAn1Jmkco99zf8jB/Og9Eq/I2eFHLzQXcX7Ecbi0fJRwYlvFZ7MkFP1f5mF2EnQohMjIj8/gQ99hVUKUYNHqxONWsfEz7m7p8OE1W0+1Gwi7GEYumtbBYO66VrTPgnxtCrOMpYG3+PFNM6L2w2KomuaR2UlyfEmBF8d0hzaw2IenETFiMwakOxLPacF4xPAgHQbPhCb6Rd/YW2fOA4L4CpiIUwN6u+XY/9JAwJ6vZ9P+3R8Upuh3f6/rhd5Os878B0me6D3iGRcO4DOrwx4NLvVVp9JMiLv1vR0B0LjSJNtNgkEnzYsoYA15OfvJdNp2qBN/giBnIorTo7GjoHaNMeS4FWRP+hJ+qKVSM8DFDtahNHfgTCq0KMVL3/dwPinMg6aYDtDTHsg0+wZDOvaYbKyJRhDWgP4RvIrSsgmaHA+4HC42L40U0vegUQtBYZb9L+3IseLv4fzUrCsXJPme1gC83bRKYFDqzJV8HjX2Lzm7/nCrwaotsYLnVD3ytcskGnqmyKneNwnHi+VAwWliHFyVwaRbk1FvCB2eDYPwEoAQwFS7KBjL2ZsobsXiiVL0e9Xv53K1c4w7fgF14wRb90Tdk2FKORDFqWMKLBJrH4jHDaJrFLKIT/vOqtW55SsllwXsVNdcdp5m9CKWRTCQ+hTvwpO9zU3IG8XE0EikKZ7YF+r129xs3GMkucGKjY0oVg6Y+5KwCdW4pEmS/J2839QZ5Pq+ecWD819eNGgWvP08wP1F4J5vmFlY7qnDLE+j+GupvL/3P8JlzopnF2OaeW82D7WvJ6BOjT/nT5dVSaRPkApfI70Fu79GuYQtkBbn2E0bya5jQjstXnt1aeVU5m1vS+yt7AjKiXokSp0bbv1jB9fhsIp3MXb46viGbJxIqGvGRR40Xp16VcDlaOgmHgsv53uP/rHNZvHQTeBCJ1xeqlSH62BSYYaA/7uHazPMU2EKXLYBNtOLswfC91BLMXLOVc6EZd1XTFIcjNoXe0zRdB/3H+dBTWrxqn9IWAC4sR7FevN/rnI+qIbv3CfLZOc38LdhLSYn+W0Ye8h9mQKXCRjWYf89txcj9pOYmTvcbl5wV48/8p6EQL7mjukP83pts1+9Oz/yrm7I7eOfOHNKNo9SvSkzfj95Bzg0JnVans4EZ3NKz72mlJT7/8Se6/fyrw0PD5C8Is/HKFjW883wkPDcW7YgOTvYJ7wdpHr0nrkp5fEUaX7SFsdnUaUy+DfAPoO+u8/v/vzJw/5FjRNCOMh4mSiesT3b+ovfu2ukDZAR93EtWBlwEhs8DUD6Njn4X+8zkljd3EaPdezUGfB+T2im/IapEMD8cpCSLAp1p+A5Ah3XTHqMPSurg7nKZ1QputTil4TkPgY2QzYHCZ/OnsuJiTgcP9/bQn2bppyUI2g0oF0WrWRQ6XpkOqQGLyYflig6qLyTZeXW9pBxliYopei59GtamteIcb6Xr2TmHHNfb+oUEmB5nWvwVmj0paEr1KCMvmlGzIllmfAm/G0qdMmZQD0QOkvv7AbMVi8dKnto2EuFw4NlpAPKDQOFYwytAM0Wo01DpzBsVnyU3gh1iQ+tubs1shxStGPclLZ2LxSRgmWnwEPm/31nSHoAlknme+JHaXUyX5PrgHz4OZ8emcAjOattkxIvN2S6ZhjFLdi6psePF60U/6xEPAqq1PCGAM=", - "page_age": null + "title": "San Francisco Bay Area weather forecast – NBC Bay Area", + "url": "https://www.nbcbayarea.com/weather/", + "encrypted_content": "EscECioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDFSJ0jI9o2K2rBDxqBoMuZrha8vmUDJNmIWoIjAZwCa/eOH5d9IaWWQT9cXz/Kx2EfTbs2V1fF+g/Ft1adsUvHO+R2RHQ5Ewuz+P6RIqygOHnZGH3gC1QJj6S1n82GRV1XfsEud23dh4WaSg6esIjJFyo01AwOiowtg4eg0wWx+XDFYVIJzEU0R76PHf1vnqTxLfNsosKVGIuUFg+aEcjoteagZzg2UKtBFX5q1EbB8XzYb1ZUdMkPFcxSBSdMQkhpKi5XXeg+AJBmh11n9mdToJHpSQs9ETH6W5HtIML1zsWqH8i/eJK8+mmKnvaz6sAZHvyeCunxBTvU8dwHc/724hikjKLmaRUUK2KGoHIZNaaaMzIzaju2kyJV2xKypq099c81mdkCVyFY1u9pqE44Db/dzJTqWZBK5LHrNplgYGQhqwCWUp7Z0QQ0+VmuBHPUPxXRParaK0d6dzc/y5tjDV0fVLme1PxhzZWIj2ynOLKSReQgs0RxMHoJOZs6ZdxCzac81LLdx3IPfdGurvKofFSjf93I/k+kbc2S88PGBQ4wyiELeUYr1fZ22tUa6DjdoAFefKcBdIiewzzSxATLjvHKQbfgPnKr9CsI5vCpq6LI/yDibTOWE4tk5clwianzv35X53rUL/9tcdOyFoeLdmVHRXhtvq0nBFObgQ0/CxsAASlX9qydb0Onh17ZX3Tvsv+94tpKN4BBgD", + "page_age": "3 days ago" }, { "type": "web_search_result", - "title": "San Francisco, California | Current Weather Forecasts, Live Radar Maps & News | WeatherBug", - "url": "https://www.weatherbug.com/weather-forecast/now/san-francisco-ca-94103", - "encrypted_content": "Es8FCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDNLGGckKftyYswszPxoMDmiHv3w66Sw+D0ysIjDd9n6R0C/xqnqcXZKvyR8pnGdX0esXL4zrqQ+1tOndVEBsDlOjkgUHxx/BBDNUx6Iq0gSoCPcHZysOCpOLDcVordlgS16IrElAkEbrErn2dW7qlY0GeIcQyEv6SsVv+V6p4/iKbq6lbGP3dF6D8TjCb5bRkmgYbtbG/2G0voaIx+zFdMbxp08YwkH5QCHRcFRjDw6cXYbgLLaOPfa5PgdzXZvH5t+HHJoMS12BCn3Sk/MYNwg+c6NhrdlWA9Uh+g/MGOQnvgTGq+qdEKAGKOL8Mhs8X6Idb2MRR8yJcnzSM6ZmX5hp3lxMRQ9V/29Hqvf+g6oWoamykkFHA43HbN9dAPjtYtzwfRNyE+2k0zJr4crpTi1VvBYuW8lo1g9Xdf0zF0r20x5C/yWSNVeGDA1IUkglw00O8lPcEqSxHubQXpojTJBBK1S5lGuFqZDP3pPDwmxnY9V1BsGU0O624H+Gg9zhQ1MofxM3GIYCTl1xqsCzI+7yH3xAFPhcDXhWfqb8Bxk4xFIahHXu0C9X5tGkQRJrN+KdluekV84mlhMTnDlBRgwn8CKrk+nBZSbEy7OcFiYuRiyO1/1iQwiqZBFoYI8QKyPH683hLvrTfmvWkOVwGkyDe4rL/VKWJN4EJYSNAUVS4s/jmeRBHtJBMY222wE+B5hCc/kfKG6XJ8va3mQcu/BTDEvpGh/DA/PdgVvJ9Ub1pWuEXrQMBLy7zx30wJ/3x+ByazCWj9fiDIE++7NvYqXgqo24vRlqT+AIXa/oI4ZbuZU0Wfm5jTX2J4dhKOumG1lq8FdTbD0BtjbX9TZ2z78nbrQUKlU4OWvKPmZQfQk99Euiz8W2TNnYO8ZQ3HRz+T0YAw==", - "page_age": null + "title": "San Francisco Bay Area, CA", + "url": "https://www.weather.gov/mtr", + "encrypted_content": "EooLCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDCTT6ISdeT/jSJ2nwBoMKene51/3GlJyBrS2IjBpQUlfApLKsh5wJ8vf5ccLGqpNJR1/0M4QDZuH9flC/wx0MMlqgBMN/oYbpynw4lkqjQogSOsj+B1bWOesmD7FPoeAnUY/R94VOFHK2zsIzwPm/r/ei6zpxLo8aVWENmATaVLNUPVovp1lD68n7cWmLDEOylMzw8zgVnvg+4gBAV5SDopGG8t+IwWZG4WXiRL1pFOIAXmwpZo7DRaJMhyVN4KFx3YZcfjNKRZ6Z6Hh83DsLEZ3Akmw2muf8ZwNqEPjRFxOQ3wAOSp3ez+xcGlRvkGcJiFHe7Di3Je8vMQ3BU31MOtUPfkUVB2Z0CuLdk3CvPOUtJk+i30GxVOi59ZBFndK702pVq6t3hzHpJPBjyljs6O33zadbHNbXZeA/Vj0plYQ1bBPyWygevNHnhu/A+1I6LZcdjrWJRQ4srC0VZdmLK/lFkBLEd3xZVNCTdABX5z414iGMjPNZiL7lgvj8sUk0ZRHf3jfNwdV6elwqovVtLa1aYF8Cg1/+GTkQm1QIZwtvzEn/JnyQysIUbG0ukpvAJTMkkaD4y7h8bHtcZSoktsDnMmO3m46LcmCGqWt4e2J3OT/9sU7rtTqxdbY7eaWl4sJw6OvfKQsvYgMMP6ptRgGPTeeA40USGJ6TErutGwt6tm1lluGc+aA1X8ufJlu7BjJ8/BdPxqT6Bs5JlDrRPWAOssM60eGNUby1DJmpWkSrhfBMgvOwBFfV1ZjS44mMNbbwF6FsRf97sXl1vdZMD2KY7USpJMQPqnGzFCYd+uBnal9hLBVrMFQ91J74fFYSmVtHvW2wXaIRTWdyQJTB816GHDuIjr0TLuTohKOE7mMefYkqBI5WKm+t1DiZGmMYTpkQujGqVHoCwwOOuvs5INv3EDOgj675NNPZPZmfliHfNfyJGd+2aW78jsw3plm5GLjOrogdxa8uFxslDILgldDRBv7IPieXLyphqJcLTLAov6rjB+VtP/z7N1syzTuCzIKc2YtRHPiIfUKGmM1W3JZ6FFUTFt7MT1onKw9LNe/4VGnfZcYLgFJnpunKqlGzaxK2olMRTXUpclJmeR3/P8BHOcbs9WuJz1jNc7TDXHdZQ31lQEWGxbwT82/LQkmo9PoApK/G7lHBeGHGtqC/nAUR/0bfDEZstiC4Tlu7pj6BlPqsrjqUesV4496NkWF/Ot4fu6kls6lwzEAitmMZmH8qt9DlWEK554G5nHkywz4i3iCj+racvgg4FTHMlMSTfcWe/EN2Fm7YuCW8lVcJl7kkEHLKdR2WZZ03VbLDgc8hgMePhcr7pQjIFgRjxWM/nfRO1zQ+dT1Kk/IRs9Y9ZMVZbz8k7LU5owqMjg0N4sSn0pZW+ZQ7G3srSsgyKScE/NY+OsSr1qVvmGTwfLkX4uBGwOYISFw3SF0FZYB14v5yBXs9Y+QK7YfvN/hPJf8Hn7kEAGg5g9uFTZZDE5DD9B5hjsr1eB+E/WSj1APs1jog7YwltF5h56CY25HP5TNAt8PxUWSXnQDlSIZDMR7wbuSlMYMTpo+9Lhv+Oqf71yXexcKK2Q6rEVzi/0WVskIwyB7JixzYxBGMOgx6DPosRLaXBPLAtV0SdblwNU3Pv8aBJsltNScwRI/Tjirb6jGW0mBeY1ewQovAWmfUPZF/XJqN6G5GFyazmyhUvb7DShAw78d+88i/cLngNja3PG2uDxUtd41pj8pAAtp8PVAavy5KHP7izdFj/7teMu2X8h4VzJSAWdPleDkVZpOjyFH7XOn+yrPL48tnmlSxaM8ebOwhmhl/DhuXIfXnksYAw==", + "page_age": "2 weeks ago" }, { "type": "web_search_result", - "title": "Weather | KTVU FOX 2", - "url": "https://www.ktvu.com/weather", - "encrypted_content": "EtQCCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDHBQfYXedtFjXqDQDBoMUIt4GTWrKrhw6ktGIjCQ9cZg0jWCVR7wF2DcBFZwpB+m5NPAyv12rU7iRtO1nWMHMleA4UkSDJ6aoc6hszIq1wHfzXq7NONKBmbXHMjSGhbrj3WJdqW13T563jnRLVNNFBddsP0T+L5oR2LqGSxjPSrTbJms+Hux0eFyBpKqqNJMC7juWyWRyg8jJj3sRcGviB1Ka6bqiqlJcvqbuHcmYr7LWMWrYObRtIosIkHooZxPxn+LBfXLoIIjMfjrlLO1bm197xqZ67x0d1EuX9J4osJ+cFJVQR0IrZZNNFjMdDHoevsbd/15BITcDcF690Dz6F+Sy+iL2VZRMjY1UpkjXpJ9SNCVehIYhCJJkZ2eMWjPMH4w7ybRWRgD", - "page_age": "3 weeks ago" + "title": "Live Doppler 7 | Bay Area Weather News - ABC7 San Francisco", + "url": "https://abc7news.com/weather/", + "encrypted_content": "Eu4ICioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDGyinkRBQZrxDpWaSxoMjtVWfchuKZV2ZujnIjAm7Fyzf9cPKWQxBK9OTagVr5zD+cY7B98L1VzfYN3FAvGbq0ZeQrvIuwKt98t6fzUq8Qcn8bH3zX+3tvz2Y7o4Vstb+TBzQEIBPgsNTTpUajRwD1cFlZ4C8oDGl8mXv7vf7SlAK5F/xi7TGhgbPA4ghFUNAVeL0lv3/9agOIjQW9OBj0329gV6yNpz0X7FtgnbtvS9q6rEdkss9Vz37L98AM7K5SaeavAauhFBvVYWrq+IVn1V0uy47PkgoraUOeBJ4JrI6a/pdTZADHYcpRRWT9udnku4nUSQSW39hnUrWVZUMqTK7vxeVA4vWIuZ9kTC+2gkjf+jk2gWpKGPkVp7KBUQtNKA802Ql6SwajbRWzt7k+Jb4fWa1CP92T545Cu/hQI2D22u+scEikIzet/9nn+VBGvE5JPf8W+hhgnr1hHznP/uoEG8Ju7TAiYswdOoGHV3PwgbMtS1G04kr6RVQkRhqUiohTf3X0CwoIIGmV1jypr75th4mSoJP4ViEFJ8+7HmsVyYi+Ej95rTXYjqd9nrN0/frEFiH9DpUJ7Qi6rwqjvY9YJdbT3hNDn/2YlH57Pi1rW7iWnQDr62IZprq1ER/hUv8giSIsOQrPDLjN5zOuYM+79tazKIglEfnoLvAnfP42yOu3D6rkLBJ/cNbvJgOwJlyVRMcUZBRVPhbp5xUCda6f8CLUyJPqoYz0gFrFiZvl/lXll/aFG/R+prSuAJQPE78Oz/3PPMXBxJtHMRfUzQE1gAtFfQICzuGcv+S3b7nbw+YXhUuB2i7L/UIfOYVIEkc5Y1llaJ4fFmTQYr7XC528dyoN5TZIDdA6em9e2h8sQ0UmCNWhoHa/dVsmCTzJaBhCmA97uWY4JJQM9sn6R1KSRFuHbe5IjkZxtpxJgxX4QOgZ53fQEXygYirWKZYC+jqcaXMXl31OQtVSwXh4xkpR4pgzWYRbw8HsnYk2R92v1p3tkwTS0DAk9eoeB43JRs6Ys/vGUdJWsHeP0qyc5D+bbkeXXEqA8ln41MMzCLmLs+dQZ0FvfLV7fyyrYGJd8camjeSX5ruljlg5vChizSvEV3Z4+WDu76kupsv3zopFTf/T1MAUlPZESoys6QkWe8MzJNJwE0LXqXuW8Wpj3bx11j1MMiu2Y2w6jICrw4HSGReNBBKVYsDNFY1I4aUlhzRdOoISUNhozuwcBl8YG3jgrmkdUkZv0eyodAIIz8n2vG4mt4Cge+PkyC/gurzNY+T+L/XbBL+uqbTN/A5w5EzlGuPgzGvtszZXup8wdw/wHGnywuFdy9L5zCakmk+AW1CWMRNzFc+Whk8M4wswegPlUX7t9stb8vUsRTYJjPFE3RCr9e6T0hHDCBnnMG6FhrTSqhuFXXYZkQWgdH+RZYwZMYgWjmqX19Rqpn0/FCGAM=", + "page_age": "6 days ago" }, { "type": "web_search_result", - "title": "Fog Today", - "url": "https://fog.today/", - "encrypted_content": "EpoGCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDMwOeyZE4pJY/EQKcBoMAyaukz8uXYHwk+qfIjDGhKpJ9gCAsAHBD3yOM56VwdECEgHNtsAadx0V5PHbr8GGHyXYG9wpCnRF6EiVtZ4qnQVgsTpM50aivIxkNkGSy29gfFGeYYbG/NcQSJQWqGgnzYhhtHkRDIp2whNuYhh6tREvV77X0CVxhy78m8Nts1bZK9tdWW4260INVLLaFsrCKnqy2t2VAczq3qu0qhUMlw9x7giot17fuYGs/WcXyfpZE/w4ca1h5x1PzYrAPNTBoxTJHbVA50Khob2nsBsJjbPOOMU2DFm6UoAnA5UskKU8Pv9okk1ai0W7LnnuNz4qC4Uk7qO/7OKu/zS0dtATPfXtAYxukMQlbQ5CgQVk0lH0eKrbOd4YuOjd76CfPiaulpjOu3Hj9aqKvFtcrR40qHRJBBYjhS+faO8TKg3FZAYvVETiqubgw79e2KueIMJs0zyaplFgtFXFt+fncXU+kUkf4fyUFHo5vfk+ibbnXH5ul4TanR6W//6HJmuTMmsIKBFrit6gg/wpC+hkcqn0uCFP8jGrdGeww7ZqpQpoU5NieJShqVZv/9iBV/rpitjDIqTlFpj+WW/FDYz3RvRt94KvRu9Mg/MI8bzoMQLwCLhUZyOqoUoCQE985Gol41DkQA1e3N+zapLAEdW/Z7+4RyBmSh58xoauCfT33FGp74OjnRpOh7g5t35dOShKUOhpXAYtXH7FZkPz2/FCZVJzolTUYTxqMD/EhHZfBdy+mAhvQ4Gvd8Z7sI3424ENrtYwr3BVh3iXJMbVhVzmDVEWHieUoY2nA32xXh22yKdsTNwWyHvkA4h31PizRA4B6GsKWTLR1DuDqPSWr+0xFREtk0B0KSUV4umkLX9QPIW2Cb75mwq5UzM9G+SD/uUMQyZ+4ICkt9FihnS6U1x9SaOprdLKXiR1hkB53JOuI3saEKQ8tr11L4bO11JPEs4l7K69npZ0m40NVCbiRutkJ+MYAw==", + "title": "San Francisco, CA Hourly Weather Forecast | Weather Underground", + "url": "https://www.wunderground.com/hourly/us/ca/san-francisco", + "encrypted_content": "EooHCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDJqjYspNmpleEKetaxoMeaD364eVcy1Dv0E0IjB2BFFVsDPzic0xz/7k4HHwwA4kcsDNx4BeLk/0jiymdDo8V0w1hV7eTuZzce/r5WMqjQZ425KPXEja50cqGhec2CIw/7o31zFbBBE6l3iijtRcIcPTlQh6Q0NX9TaAlAE28Uf6JlsEhySrC51qS4qJ08FwaVRP7hYpjJnL+SNWDrsGGKPhMMRSQB6/Mkx2hLKKaILdBcJ0kiD1BjrXjj5kLTWBv7G53qj5shajORgHfmhVYkVtzDPxbnM6x8JDfckvDFArCMIiwtkrBmxCUTgxXYaWQE2FhP3G+ePryj8wBzjyk8Vs/FJoaR/ayheTbG2UfoSzePWyfxUI6Ilhu+/9+GZ2FhxlUOV7SRZuBM0aWIroZWQeOJih+rH6sETurWilNRdbUmbaOJhReTwli3G0OXqUxj61uqoagis9DTGHOUNKDM8OUqxifsRYve8mEmOelKprB2azcedtFNYpwW0H1heTlXcYtFC83p/oOZ7N+g2dEwI9pf1BlktgQqiU4CH95+8ervYCSb98BZlCKI3TsQ2pL6tCVcFmUnpCmu0kODZJBpQyR6aY6rm2N+NpeHC1NCrzNz2GpRax77ZaFIs0ewn3mLVIU+yYC5XlbGwA4G62tACLDCOXM4qdiNm+kqi4TkWxW+D4QDowNUFwb3eIADfvS/9Z6eJcF6Fiq7M6G7UrLLOFKSjV7PxStyX5ZJ3du6nR5MaFIR23HNJYYjFZUnKbSAEM/Q1AynzCcywu++WoJFkwB7iMAFHsy3REvqV22USCPuH2721EQm2D358tlR0d6uPl1eeA3WXs10bmBzWqumOORu+K2lj+sfgeex+LwUMZh8zJM+8DlCQTwbRpBi6Z4MpCx4od5XxL+2OvyHD92wapKk7oa30oM/M30QKgVlDizxnh3d9Jse/tJDucWGhw4laGd8bQVABfndlkyczyZvk5xj+nDEMm1jrXXZ8+Hqm2yoNNF/Ob1FwKWr9Gn5ZiN465OPA3d9qA0wtPUDRbcSDwWlL9M/dnhFhPEtQgf6WL2uXUAyBN/QLMCsFTxhgrxcidai/wndRZjXdjAgBrbXRLS2VHGu8KIJAz6/8fmtGi8ElcI3Fo40zYU41zGAM=", "page_age": null }, { "type": "web_search_result", - "title": "San Francisco Bay Area weather and First Alert Weather forecasts - CBS San Francisco", - "url": "https://www.cbsnews.com/sanfrancisco/weather/", - "encrypted_content": "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", - "page_age": "4 weeks ago" + "title": "San Francisco, CA Current Weather - The Weather Network", + "url": "https://www.theweathernetwork.com/en/city/us/california/san-francisco/current?_guid_iss_=1", + "encrypted_content": "EpwCCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDERaOLj0hp1f2d3pdxoM0Zp89UizgQdTlV8KIjCFUJNONXXhf2Azrvyo7r4Ajux52Pfsummcdpvt+2t5VUydmq43hXOLLGzbc1hdL38qnwG7FS1Ffi0jmoaePNTXWZSPiCZ9C9H5q/cm39dQl4DD4EkhP6Bs3Lqp8wMrWMGUXrUEfdhsKUVA/RhjJ3JcMfQEEWhBAs6+30RdLYzl2VaqRJNjHhFC3nkvUgsld5j4sC+5Y7jcIEqZQfCW2BDJTomziiSUevT8nBqQYRO3w97I/lk9O10a7aDblp0+pSk4KSJkntNFT2tpyUIelQpoLu8YAw==", + "page_age": "2 weeks ago" }, { "type": "web_search_result", - "title": "San Francisco, CA Current Weather - The Weather Network", - "url": "https://www.theweathernetwork.com/en/city/us/california/san-francisco/current?_guid_iss_=1", - "encrypted_content": "EpwCCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDPyCIpf18wmD2HpT3xoMTFduigKcaaj2EH0cIjAqHqZeoD5ISXHF5bJmC7m45trOlI9caV2BwXvmkbczUVstau4WjEHCnoVC8E7gC8UqnwEX/hr/LOOmDMks7MMNkqQrDte2Prh4DaJkKC3yoacmNV/6spCSSq01u41FKnBeHZNIvY9QYxQ5nZXcSPbwHqy1P+XLL3i/CWH7hFHFA8Kq2U8u2tn6ZynOMjRBEH/4c3PulDfrfFUuR1uRA1UNCObKn8s0JZEnQijWzD6HEL+Vr4YxYDC4aJesMu9xpHjC8zHZ38/dbfs1KRQyEDhNeMcYAw==", - "page_age": "4 days ago" + "title": "San Francisco, CA Weather Forecast, Conditions, and Maps – Yahoo Weather", + "url": "https://weather.yahoo.com/us/ca/san-francisco", + "encrypted_content": "EswBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDPJ9RfbpDzf5kJxjcxoMHs4sqi4AH1av+haiIjDwPMwJGgSBWeyKxY0OBjTs4Mtss0DNG0STPbPHr0zJXL4mCloNdWfPEJNX2jKMWbAqUN2MnCBU9rCqDB1Da7+XPbgIGo7Ua3J1CEIy3H2wgS3Sgub98ELQMdLzCfjTRUs4qsLJg7QmHzVZqi6RNUO0qJkdwNd6H58ayrlhA/gh3hlxGAM=", + "page_age": "2 weeks ago" }, { "type": "web_search_result", - "title": "San Francisco Bay Area, CA", - "url": "https://www.weather.gov/mtr/", - "encrypted_content": "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", - "page_age": "2 days ago" + "title": "San Francisco, CA 10-Day Weather Forecast | Weather Underground", + "url": "https://www.wunderground.com/forecast/us/ca/san-francisco", + "encrypted_content": "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", + "page_age": null }, { "type": "web_search_result", - "title": "San Francisco Bay Area weather forecast – NBC Bay Area", - "url": "https://www.nbcbayarea.com/weather/", - "encrypted_content": "EsMICioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDLWt5CNE5+gd82RwBBoMihbjGRpjOMvBC+/rIjD6iKDuNo8ZRmIjMrToH9UflyCKZS1OpmD6kSF8elrc/8eXnUoEqR9kFJKzc10nfP4qxgfkkn2d1VG8OfKx3bX8XOJd4A7CfATqIk0i1ONXaIck1+Ts9hYU729hjbmNzup2uspCIxezHDTG/BkLFQc7Aa+kWExbAZHXcmotGOjdLjldyI+129pTuZEHav1sY9yazcmI0qpzJ0kRISwPtN5SnEycKVD7nEUR004HxDG/2BSO0cYLfBIJ0W2pVm19aUi7kCoFSl1UmwEEgOA3BN1J1ms+3P6gGuF9LIsjnVLM4omv9G3cN0YeR6h9LUMpFXQMbPRRXAzfdJKe0zc05r+4Wq0DkvNFfdKL7d23AIcObDFEAst7rSu7X2oJz7zosS0WsyKvYer/ss948tehjne4qGfEZfySMjoNlW1WnLNjWNo57IwAwOdVOyFYfUSnn7MI7l7mjhKg8NeHMVBj/fYFHimEaBsd78QIL1wIGnerku98wDiE9+s7mZwXM3vKh/ppn9TvgOB1C76UKuOaYWGCWaUaYFA9jrgnEg/GIgGZMqmrCpe9xUwsVopkg0Rk82I1lGC/Uyumu+X7FZYrixuhCh/IvlWSpkiUzaGwQGD/wQnkZc/NU1pWKR1yNlkGVbyQV155YWINOXvxyY76FvVKYJYDaRjQjpI74lYToNUK+ucVht0j71iKEus/9Ki6AMFS0606P5Pgzp/wxhJJPN9GQioH4UWNyk8zJBkWgyJGQVMQj/wUCQydFiE2lwe9vpb9/Xhbidem0mnbSIbTufVPluxfYeTNJPhB/aJd6xLQL7cDcHquHbUprXgyBFeYnoSzfdDMmH3AFkXsyvAF94+HiF1gIUCJxCm3W5WK8PiXsAlUul8ySYhXsJbXd2ojRIg6rwIzqsdmh33sWZx88Xwi78Pmn+6J7NzakEVGVj6+5wH17PTXtdln2Nd22QOzvn6SWmyyv50GwxpdEluMnAeyzzkkp6zGrBoSpKFHzjqrjYBiXbQWMut1+q0lK0b1SRTOChWCDjuG7FedM/n1yx4Zs/WYRauSn4DBBzU0OmvD0rcZGQPaHkXbh7PqNBZW4yVhSIO22MnlrN8flUWdJUK4xDGpTXeBtjh8eiwu9fk4+ACqWhxyjvNyrcfhcV8ScmG1tKFjsU8C2Z817zjqPiXcDSRrhJ5b35banK5n/2Yv47PAQXnfjNlDk4s9b49PhIaN5WnXLJSWpJZpz1zY5Ct7kF8ZzYPsqgSFPCcbEtCN/QEpLsZLfvZM1JYMUknWwrt5EGGrmGK9dqhOpOLBccWQ0yAEXzE8UbfuWS26ZttHO01ZCzzookNVB/0342QCCI3Op7Za3udzQoUYAw==", - "page_age": "3 days ago" + "title": "National Weather Service", + "url": "https://forecast.weather.gov/MapClick.php?lat=37.7771&lon=-122.4196", + "encrypted_content": "EpoICioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDMYOcmEg/FuB6iIBCxoMXD+eYmbQ32fGHEnfIjCuJ753WtDp74k2DWRwVt0+7FFfJGy5rAieczvpxE1vCjdzf7GBl5x27cDkQBmqH/cqnQefd6vHu0LIrNB/h+/BGVaILcd5eukoOEaCy61gcOOOflFOMz++6NNL7jRRs6nH5yBWCFHfQJ5umWpDjZTYyl2bButUJcQyOEd1THIF7M7RFrN8DiLaROHBP52DFvcr9ZgWkJNoTvRI9KTnHIEhh5uYkRT3tqE/uIhjUaRzOa6WXNwUn9/sMmMKfsiqE1qN5R1fhH+dUGDvpAtiqVR5HS0VOaq37BmLq2uSPCloQ5IYzsSIC81OJzJQ7h13JuCiwQ53MTzdWgSzoCdySfZZidHh/kQKW25yLvbSMMQsIS/KGVOvvrYXuN94V45IprQx0bV3n3lp+aXWQO4jlSuSzaH8gSOFxt40iEijfVpTv+WX2Px5rDJtu7XAv6XZKKA7kpunXQTbUkYjgbiUsINWLCrc/t3aPgHy+s4yifptYYWWSzTN6tRw1QYHzEr+OXTcPW4BolbwmoCwMKztIljwVZt3deMi+Rq6fJ/yx2gAUdPjAdkA1PHk26VkfEDqOs0AryfbCwlLT7GKL1nyUXvaqah4F2vfNvSFW0wz1Ne1fpUrHdGGFi+3FlnXqZOboaJeqJAFX/8TIXguXjGgVznf/A2eEqv/Pya+L5IQZti1MD7B1Y6ttuy2fWbIFwVQbsd2w0ES2Rs6+07a+dQWKawJfSD8qwq57dakmgUGJFYQ6ES5TElIIIQpz+CGp0UzvZT52EcLPQy1CwntryyPdc2jmZvfJbZX8iC63I4vTc5uBiM8QLGJrbdhX5q/ZB4DlfN7/VlP9BvckPuwMsNKcuwe6SVnEQJVG5CIjv1A7xUNxAkLYp5GpFvNNI63B2ekCrnFG9Q77+DAGY82zvQsMBQmZ9EUqYPdGOJBZbfQjsaVxxjOCQ9/mJMWd1OlzCdk1a0V63VIhbDbSTmVb7WnJCRoQzPzXvV+yrNWfPyb1TDwSnj9UCqQoZMTVD+5xcAVe8baRxJ4Y7dLsQO/Jy1hgHojYS/56GsGWY71EG1SNpxhU7IT/BjILQKwD5Ep31XGRoOlecb0extPpPMzxTyW6RQjlodSNqLugdKLO6AOmEwzLlxyGYG3E8YA45VGkbkfRsEhGvUO8VSZNovRr/xJYYX0Z8S+2K1VFdrKZLt2MxAGvw39f4RqjnrCBBdYxWZhv/HqD/FxNWhQD7oIjb6qmgrBe+ClE4/sT3h6BoTpUohpOPkT0R/QgctMB/+bJ5GRUmR/gGxvgGo7xioI6L6otadMGAM=", + "page_age": "2 weeks ago" }, { "type": "web_search_result", - "title": "San Francisco, CA Weather Forecast, Conditions, and Maps", - "url": "https://www.yahoo.com/news/weather/united-states/california/san-francisco-2487956", - "encrypted_content": "EswBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDFQaQjU3YjkQyuhdkBoMb/hFX/Eppc86YUC5IjABwWR/z3hhZ/1IOYeauzdY38Mc5cBeKJQaiNeYaG5mfhwxCZ0icRVJm5bw6zjbpIQqUD036oskC4KdqLkBFUyYwxJcc/EbdxXDNyb0Qv6IBBa6PHS/PvLkMFuXoBx7YYDFh6f6b9dSDpio9Jjtps/1o/4RMpBknxqLvxs5x+utHWSsGAM=", - "page_age": null + "title": "Weather", + "url": "https://www.sfchronicle.com/weather/", + "encrypted_content": "Ep0FCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDGevzcC7UzIfLJ81UhoMvGN6KO4xjGOrd1iCIjAdD4yMW8M9FCsvN6UgF5QiPheayABNkmgxexO0Os31VFiLApD8owM7QIvzZwLkBGIqoAS5RP5o8vvmvSiWhJEeUTdsJnmrMI52gxnkVpoMbeVJCWtZAj3tsokyvkheMYKzJ3MppFNV3ovAQ/H0O3ttHdtlEbmywifMCBiC+TeuIRFz4DMUWvIuNQSpfCrhB0UZY8/FzlfY+I1cHh/w4/J/Vy0TJDMs22DQ4iqtBje03xBIdMN7P8+xKNpws+rduchyzlpmETzmtIxV8C+YTwIKO5dKpF3vZtE30RS501M4jDMIFUBHksv/DjDPL+6bewDiGpuaemhLYcbjrDMN0BCNjaG6FXLgeeiCXYyLvpZ+SrZjx+zA6AVBsuvLMLywyOylqZf1hiWTZYXR+BOIo65XiURie0N2vabGmtZPf2JnAouEooztjXkod2hci5ONa2eFEIRzcvYp3LHW2/E6F4TTCkZqrvDpq/IvBrh+Fm/Go6x+qZViALxrKwCFtgDAAgVCFBZ/dHUF7AmJGegq65tIt4NzbnnzfKcGQ6+i/PfIVIAFrQNg1hPddFxKyqZLfDGvBFLyM2+E9nmXQ7vUTzRNVE1RRPFtI4iZ3UpSV8fDuQVJ0tfvjxelAsN+xFRweAJMttF8AF/Dm50N9YAGt58ajyhHzUSDPvOu/RDgmhTDhmBjAN1+tTv2Z/PI6N1X8C3AIxAuXINbmlJzRRw8qD4Dwp3DBk9ms2/zBvZx4QIrUpvy6KgopM7hTibTaXq6jkp8tWHCiYZA8BzTy11shM9/aaPrGAM=", + "page_age": "4 days ago" } ] }, { "type": "text", - "text": "Based on the current weather forecast for San Francisco:\n\n" + "text": "Based on the latest weather information for San Francisco:\n\n" }, { "citations": [ { "type": "web_search_result_location", - "cited_text": "zoom out · Showing Stations · Hourly Forecast for Today, Friday 12/05Hourly for Today, Fri 12/05 · Today 12/05 · 6% / 0 in · A good deal of sunshine. ", - "url": "https://www.wunderground.com/hourly/us/ca/san-francisco", - "title": "San Francisco, CA Hourly Weather Forecast | Weather Underground", - "encrypted_index": "Eo8BCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDF3vaU6EU5iBxOhrQRoMFYIQ8+XE15PuZ0pKIjA4FQSdosGf5L6Ol7fIfpIJy5lid8Uy84RIIDuicPTQXDGtRjCWuP3CnNDVv36D3ZcqEzEyHm/WXGjf92QPwdyhgZaoFv0YBA==" + "cited_text": "... Mostly cloudy, then gradually becoming sunny, with a high near 53. North wind 6 to 9 mph. ", + "url": "https://forecast.weather.gov/MapClick.php?lat=37.7771&lon=-122.4196", + "title": "National Weather Service", + "encrypted_index": "EpEBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDMIBBVqNadugmkTbaBoMs553Ug3Vho9D3eCTIjCfbTEWsDAyX9i2khTVn/XNMbBM9f9huTgA9oHpYQ9NUvoIrXd8t79PlGQgxQkZGnQqFT9D3bkKUW4ig+qm+PuCZUlrTIVDFxgE" } ], "type": "text", - "text": "Today is expected to have a good deal of sunshine" + "text": "Today is mostly cloudy becoming sunny, with a high near 53°F and north winds of 6 to 9 mph." }, { "type": "text", - "text": ", with " + "text": " " }, { "citations": [ { "type": "web_search_result_location", - "cited_text": "High 58F. Winds N at 5 to 10 mph. ", - "url": "https://www.wunderground.com/hourly/us/ca/san-francisco", - "title": "San Francisco, CA Hourly Weather Forecast | Weather Underground", - "encrypted_index": "EpEBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDBwrHoCSxWPWRdrHcRoMHH5lBQOZwtO5+k3ZIjC8kOWVDaoLDQ3MIbdxZvI+A/1U4V+LsjOwGwXfeg7+HfnQzYBCygEh6mN6YJPxwAgqFXGba3zldKQEEGzVniRgCiaAxyOs6BgE" + "cited_text": "... Patchy fog after 1am. Otherwise, increasing clouds, with a low around 51. West wind around 6 mph becoming calm after midnight. ", + "url": "https://forecast.weather.gov/MapClick.php?lat=37.7771&lon=-122.4196", + "title": "National Weather Service", + "encrypted_index": "EpIBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDHV+VV5Q7nPfdMZFphoMpldJI+k3ybGJX49mIjBjlbHreJdOhOW3sdCBiNI/riufEek0c38POv6UD4WumGjbHTp2espS7yMTHXWQi6wqFjwtuHHywcl5v/QUQw6LN9yFupcGX0AYBA==" } ], "type": "text", - "text": "a high of 58°F and winds from the north at 5 to 10 mph" + "text": "Tonight will have patchy fog after 1am with increasing clouds and a low around 51°F, with west winds becoming calm after midnight." }, { "type": "text", - "text": ". " + "text": "\n\n" }, { "citations": [ { "type": "web_search_result_location", - "cited_text": "Tonight 12/05 · 8 % / 0 in · Partly cloudy skies. Low 47F. ", - "url": "https://www.wunderground.com/hourly/us/ca/san-francisco", - "title": "San Francisco, CA Hourly Weather Forecast | Weather Underground", - "encrypted_index": "EpEBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDOjg/daPzBMpVqtcBRoMFvN5srtrqjEwD4K9IjCOroiNwibFTmcvkWIaB32TxH8phnMjZJlXqBRfLN5USQuslXbr9vIEz21IMJzVqrcqFfb09hoAOJn6U7was5gtdsojZeftwRgE" + "cited_text": "Rain likely, mainly after 4pm. Patchy fog before 1pm. Otherwise, mostly cloudy, with a high near 61. Calm wind becoming west around 6 mph in the after...", + "url": "https://forecast.weather.gov/MapClick.php?lat=37.7771&lon=-122.4196", + "title": "National Weather Service", + "encrypted_index": "EpMBCioIChgCIiQ1NTc2NjExZi1hMWVlLTQyN2MtOTgwMC0yOThkOTU3OTg5OWMSDBtf9on2TcUs4b5m3RoMWAxpMenGV3ROH7v7IjCeRMgMeBvMGQPuEgySrmc6fW+VoCttA0DR7QtUsA8L1t+96LuIVqGB9ggkUU6S1BsqF2N0JIVyO+uWrBI6Euuu58JTXtOeRzr/GAQ=" } ], "type": "text", - "text": "Tonight will be partly cloudy with a low of 47°F" - }, - { - "type": "text", - "text": "." + "text": "Tomorrow looks rainy, mainly after 4pm, with patchy fog before 1pm and a high near 61°F, with a 60% chance of precipitation." } ], "stop_reason": "end_turn", "stop_sequence": null, "usage": { - "input_tokens": 9656, + "input_tokens": 9360, "cache_creation_input_tokens": 0, "cache_read_input_tokens": 0, "cache_creation": { "ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0 }, - "output_tokens": 176, + "output_tokens": 257, "service_tier": "standard", "server_tool_use": { "web_search_requests": 1 diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ad005e89-f72b-4f0e-941a-9ec3473c1bc8.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ad005e89-f72b-4f0e-941a-9ec3473c1bc8.json index 4dfa3aa7..bca3569d 100644 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ad005e89-f72b-4f0e-941a-9ec3473c1bc8.json +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ad005e89-f72b-4f0e-941a-9ec3473c1bc8.json @@ -1,29 +1,91 @@ [ { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "588" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 17:23:46 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk9BvJJL9DSpQAbDcRJA", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1525", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a84c0eb5eeb656e-AMS" + "server": "cloudflare" }, "body": { "model": "claude-haiku-4-5-20251001", - "id": "msg_017qL8GBMqwCsEmXujM6p775", + "id": "msg_01SFtccfdwXnkEeTTntY4wrA", "type": "message", "role": "assistant", "content": [ { "type": "tool_use", - "id": "toolu_01EqKdVnvSZkNUXcxkJZsva7", + "id": "toolu_018iSyDrY8EQQAH313R6xCkA", "name": "get_weather", "input": { "location": "San Francisco, CA", @@ -48,30 +110,116 @@ } }, { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "960" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + }, + { + "role": "assistant", + "content": [ + { + "id": "toolu_018iSyDrY8EQQAH313R6xCkA", + "input": { + "location": "San Francisco, CA", + "units": "f" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_018iSyDrY8EQQAH313R6xCkA", + "content": "{\"location\": \"San Francisco, CA\", \"temperature\": \"68\\u00b0F\", \"condition\": \"Sunny\"}" + } + ] + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 17:23:47 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk9C3uCDkHzzBQZKzQ5h", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1453", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a84c0f65f6c656e-AMS" + "server": "cloudflare" }, "body": { "model": "claude-haiku-4-5-20251001", - "id": "msg_01FvTMNojoLmBYw4KxJXB27y", + "id": "msg_016diNmBsVwjnEodFdXMgg4j", "type": "message", "role": "assistant", "content": [ { "type": "text", - "text": "The weather in San Francisco is currently **68°F and Sunny**. Great day to be out and about!" + "text": "The weather in San Francisco is currently **sunny** with a temperature of **68°F** (20°C)." } ], "stop_reason": "end_turn", diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/e4c374b8-ae08-48f3-96e5-9d28066820b0.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/e4c374b8-ae08-48f3-96e5-9d28066820b0.json index 47ee9758..9886a759 100644 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/e4c374b8-ae08-48f3-96e5-9d28066820b0.json +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/e4c374b8-ae08-48f3-96e5-9d28066820b0.json @@ -1,36 +1,87 @@ [ { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "530" + }, + "body": { + "max_tokens": 4000, + "messages": [ + { + "role": "user", + "content": "Write a detailed 500 word essay about dogs, cats, and birds. Call the tool submit_analysis with the information about all three animals. Note that you should call it only once at the end of your essay." + } + ], + "model": "claude-sonnet-4-5", + "tools": [ + { + "name": "submit_analysis", + "description": "Call this LAST with your final analysis.", + "input_schema": { + "additionalProperties": false, + "properties": { + "summary": { + "title": "Summary", + "type": "string" + } + }, + "required": [ + "summary" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 17:00:10 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk7N2gZrR5LZ96asq2gB", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "22362", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a849dd93c6bae1c-AMS" + "server": "cloudflare" }, "body": { "model": "claude-sonnet-4-5-20250929", - "id": "msg_01E3KgQxmugcS6yfwKeWkXz1", + "id": "msg_015MZWkRKxG26Adm8rrYp2YL", "type": "message", "role": "assistant", "content": [ { "type": "text", - "text": "# The Fascinating World of Dogs, Cats, and Birds: A Comparative Look at Popular Pets\n\nThroughout human history, animals have played pivotal roles in our lives, serving as companions, helpers, and sources of joy. Among the most beloved creatures that share our homes are dogs, cats, and birds—three distinctly different yet equally captivating groups of animals that have captured hearts worldwide.\n\n## Dogs: Humanity's Loyal Companions\n\nDogs, scientifically known as Canis familiaris, have earned their reputation as \"man's best friend\" through thousands of years of domestication. Descended from wolves, dogs have evolved alongside humans for approximately 15,000 to 40,000 years, developing an unparalleled bond with our species. Their remarkable diversity is astounding, with over 340 recognized breeds ranging from the tiny Chihuahua to the massive Great Dane.\n\nWhat sets dogs apart is their exceptional loyalty and trainability. They possess an innate desire to please their owners, making them ideal working animals in roles such as service dogs, police dogs, and therapy animals. Their acute sense of smell—up to 100,000 times more sensitive than humans—and keen hearing make them excellent guardians. Dogs are highly social creatures that thrive on interaction, requiring regular exercise, mental stimulation, and consistent companionship to maintain their physical and emotional well-being.\n\n## Cats: Independent Yet Affectionate\n\nCats, or Felis catus, present a fascinating contrast to their canine counterparts. These elegant felines were domesticated more recently, approximately 9,000 years ago in the Middle East. Unlike dogs, cats retain much of their wild independence, making them perfect companions for those who appreciate a more autonomous pet.\n\nCats are renowned for their grace, flexibility, and hunting prowess. Their retractable claws, exceptional night vision, and lightning-fast reflexes make them formidable predators of small prey. Despite their reputation for aloofness, cats form strong bonds with their owners, expressing affection through purring, head-butting, and kneading. They are relatively low-maintenance pets, being naturally clean animals that groom themselves meticulously and can be easily litter-trained. Cats are ideal for apartment living and busy individuals, as they require less direct attention than dogs while still providing meaningful companionship.\n\n## Birds: Colorful and Intelligent\n\nBirds represent an entirely different category of pet ownership, offering unique rewards and challenges. From small budgerigars to large parrots like macaws and African greys, pet birds display remarkable intelligence and personality. Many species can learn to mimic human speech and perform complex tricks, demonstrating cognitive abilities that rival some mammals.\n\nBirds are social creatures in the wild, and pet birds require significant mental stimulation and interaction to thrive. Their vibrant plumage, melodious songs, and playful behaviors bring joy and liveliness to any home. However, bird ownership demands commitment—proper housing, specialized diets, and regular veterinary care are essential. Some larger parrot species can live for 50 years or more, making them lifetime companions.\n\n## Conclusion\n\nDogs, cats, and birds each offer distinct advantages as companion animals. Dogs provide unwavering loyalty and active companionship, cats offer independent yet affectionate relationships, and birds deliver intelligence and beauty in compact packages. The choice between these wonderful creatures ultimately depends on individual lifestyle, living situation, and personal preferences, but all three have proven themselves as irreplaceable members of countless families worldwide." + "text": "# A Comparative Look at Three Beloved Companions: Dogs, Cats, and Birds\n\nThroughout human history, animals have played integral roles in our lives, serving as companions, helpers, and sources of joy. Among the most popular pets worldwide are dogs, cats, and birds, each offering unique characteristics and forming distinct relationships with their human caregivers.\n\n## Dogs: Loyal Companions\n\nDogs, often called \"man's best friend,\" have been domesticated for thousands of years, with archaeological evidence suggesting this partnership began over 15,000 years ago. Known for their unwavering loyalty and affectionate nature, dogs have evolved alongside humans to become remarkably attuned to our emotions and behaviors. They possess an extraordinary sense of smell, hearing far superior to humans, and an innate desire to please their owners.\n\nDogs come in hundreds of breeds, ranging from tiny Chihuahuas weighing just a few pounds to massive Great Danes standing over thirty inches tall. This diversity allows people to choose companions that fit their lifestyle, whether they need an energetic running partner, a gentle family dog, or a working animal for herding or protection. Dogs are highly trainable and social creatures, thriving on interaction and requiring regular exercise and mental stimulation. Their pack mentality makes them naturally inclined to form strong bonds with their human families, often displaying protective behaviors and genuine excitement at their owners' return home.\n\n## Cats: Independent Spirits\n\nCats represent a different approach to companionship. Domesticated approximately 10,000 years ago, these elegant felines maintain a reputation for independence while still forming deep attachments to their human companions. Unlike dogs, cats are typically more self-sufficient, content to entertain themselves and requiring less constant attention. This makes them ideal for people with busy schedules or smaller living spaces.\n\nCats are natural hunters, possessing remarkable agility, excellent night vision, and retractable claws that aid in climbing and catching prey. They communicate through various vocalizations, body language, and the famous purr—a sound that often indicates contentment but can also serve other purposes. Cats spend significant portions of their day grooming themselves, making them exceptionally clean animals. While they may seem aloof, cats often display affection on their own terms, seeking out their owners for cuddles and play when the mood strikes them.\n\n## Birds: Vibrant and Vocal\n\nBirds offer yet another dimension to pet ownership. From small finches and canaries to larger parrots and cockatoos, avian companions bring color, song, and remarkable intelligence into homes. Many bird species, particularly parrots, possess impressive cognitive abilities, capable of learning extensive vocabularies, solving puzzles, and even demonstrating emotional awareness.\n\nBirds require specialized care, including appropriate caging, specific diets, and mental enrichment to prevent boredom. Social species like parakeets and cockatiels thrive on interaction, while some birds can live for decades, representing a long-term commitment. Their ability to mimic sounds and human speech fascinates owners, and their playful antics provide endless entertainment.\n\n## Conclusion\n\nEach of these animals—dogs, cats, and birds—offers unique benefits and challenges. Dogs provide active companionship and loyalty, cats offer low-maintenance affection and independence, and birds bring beauty and intelligence in compact packages. The choice between them ultimately depends on individual lifestyle, living situation, and personal preferences, but all three have proven themselves worthy companions throughout human civilization." }, { "type": "tool_use", - "id": "toolu_01M3sFZ6BzuiJc7mqwv79u8e", + "id": "toolu_01TGC8C88xDaCfXuuHhQqo8j", "name": "submit_analysis", "input": { - "summary": "This comprehensive essay explores three popular categories of companion animals: dogs, cats, and birds. Dogs (Canis familiaris) are highlighted as loyal, trainable companions domesticated 15,000-40,000 years ago, with over 340 breeds and exceptional abilities in smell and hearing, making them ideal service and working animals. Cats (Felis catus) are presented as independent yet affectionate pets domesticated around 9,000 years ago, known for their grace, hunting abilities, low-maintenance nature, and self-grooming habits. Birds, ranging from budgerigars to large parrots, are described as intelligent and colorful pets capable of mimicking speech and performing tricks, requiring significant mental stimulation and potentially living 50+ years. The essay emphasizes that each animal type offers unique advantages: dogs provide active companionship and loyalty, cats offer independent relationships suitable for busy lifestyles, and birds deliver intelligence and beauty. The choice among these pets depends on individual lifestyle, living situation, and personal preferences, with all three serving as beloved family members worldwide." + "summary": "This essay explores three popular pet categories: dogs, cats, and birds. Dogs are characterized as loyal, highly trainable companions domesticated over 15,000 years ago, available in hundreds of breeds with varying sizes and temperaments, requiring regular exercise and social interaction due to their pack mentality. Cats are presented as independent yet affectionate pets domesticated approximately 10,000 years ago, known for their self-sufficiency, hunting abilities, cleanliness, and suitability for smaller living spaces or busy owners. Birds, ranging from small finches to large parrots, are described as intelligent and vocal companions requiring specialized care, capable of mimicking speech, solving puzzles, and providing long-term companionship with some species living for decades. The essay concludes that each animal type offers distinct advantages—dogs provide active loyalty, cats offer low-maintenance independence, and birds bring beauty and intelligence—making the choice dependent on individual lifestyle and preferences." } } ], @@ -44,37 +95,72 @@ "ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0 }, - "output_tokens": 1046, + "output_tokens": 992, "service_tier": "standard" } } } }, { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "compaction", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "1666" + }, + "body": { + "max_tokens": 4000, + "messages": [ + { + "role": "user", + "content": "Write a detailed 500 word essay about dogs, cats, and birds. Call the tool submit_analysis with the information about all three animals. Note that you should call it only once at the end of your essay." + }, + { + "role": "user", + "content": "You have been working on the task described above but have not yet completed it. Write a continuation summary that will allow you (or another instance of yourself) to resume work efficiently in a future context window where the conversation history will be replaced with this summary. Your summary should be structured, concise, and actionable. Include:\n1. Task Overview\nThe user's core request and success criteria\nAny clarifications or constraints they specified\n2. Current State\nWhat has been completed so far\nFiles created, modified, or analyzed (with paths if relevant)\nKey outputs or artifacts produced\n3. Important Discoveries\nTechnical constraints or requirements uncovered\nDecisions made and their rationale\nErrors encountered and how they were resolved\nWhat approaches were tried that didn't work (and why)\n4. Next Steps\nSpecific actions needed to complete the task\nAny blockers or open questions to resolve\nPriority order if multiple steps remain\n5. Context to Preserve\nUser preferences or style requirements\nDomain-specific details that aren't obvious\nAny promises made to the user\nBe concise but complete—err on the side of including information that would prevent duplicate work or repeated mistakes. Write in a way that enables immediate resumption of the task.\nWrap your summary in tags." + } + ], + "model": "claude-sonnet-4-5" + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 17:00:24 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk7Ph89FopGzZt9w21Em", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "13504", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a849e663eb0ae1c-AMS" + "server": "cloudflare" }, "body": { "model": "claude-sonnet-4-5-20250929", - "id": "msg_01DAVpeXCGJPScdQDECVbF8z", + "id": "msg_01QJzgcThZBbu3o4RMRKWYAz", "type": "message", "role": "assistant", "content": [ { "type": "text", - "text": "\n## 1. Task Overview\nThe user has requested:\n- Write a detailed 500-word essay about dogs, cats, and birds\n- Call the tool `submit_analysis` ONCE at the end with information about all three animals\n- The tool should contain compiled information from the essay about all three animal types\n\nSuccess criteria:\n- Essay must be approximately 500 words\n- Must cover all three animals (dogs, cats, birds)\n- Must be detailed\n- Single tool call at the very end containing analysis/information about all three animals\n\n## 2. Current State\n**Completed:** Nothing has been completed yet.\n\n**Files/Outputs:** None created.\n\n**Status:** Task not started. No essay has been written, and no tool has been called.\n\n## 3. Important Discoveries\nNo technical constraints have been uncovered yet, as work hasn't begun.\n\n**Key requirements identified:**\n- Need to understand the `submit_analysis` tool parameters (what fields it accepts)\n- The tool call should synthesize information about all three animals from the essay\n- Only ONE tool call should be made, despite covering three different animals\n\n## 4. Next Steps\n**Immediate actions required:**\n\n1. **Write the 500-word essay** covering:\n - Dogs (characteristics, behavior, role as pets, etc.)\n - Cats (characteristics, behavior, role as pets, etc.)\n - Birds (characteristics, behavior, role as pets, etc.)\n - Ensure balanced coverage of all three animals\n - Aim for approximately 500 words total\n\n2. **Call `submit_analysis` tool once** after completing the essay:\n - Structure the tool call to include information about all three animals\n - Likely format: summarize key points about each animal type\n - May need to check tool schema to understand expected parameters\n\n**Priority:** Write essay first, then make single tool call.\n\n**Blockers/Questions:** \n- Need to determine exact parameters for `submit_analysis` tool when ready to call it\n\n## 5. Context to Preserve\n- User specifically emphasized calling the tool \"only once at the end\"\n- Essay should be \"detailed\" - aim for substantive content, not superficial\n- All three animals must be covered adequately\n- Word count target: approximately 500 words\n" + "text": "\n## 1. Task Overview\nThe user requested a detailed 500-word essay about dogs, cats, and birds, followed by a single call to a tool named `submit_analysis` with information about all three animals. Key requirements:\n- Essay must be approximately 500 words\n- Must cover all three animal types: dogs, cats, and birds\n- Must call `submit_analysis` tool exactly once at the end\n- The tool call should contain information about all three animals\n\n## 2. Current State\n**Completed:** Nothing has been completed yet. This appears to be the initial state of the task.\n\n**Not yet done:**\n- The 500-word essay has not been written\n- The `submit_analysis` tool has not been called\n\n## 3. Important Discoveries\n**Constraints identified:**\n- The tool `submit_analysis` must be called only once, not separately for each animal\n- The tool call should occur after the essay is complete\n- Need to determine the proper parameters/format for `submit_analysis` tool (this information was not provided in the initial request)\n\n**Uncertainty:**\n- The exact structure and parameters expected by `submit_analysis` are unclear. Will need to infer or use reasonable structure when calling the tool (e.g., might expect JSON with animal names and their characteristics, or separate parameters for each animal)\n\n## 4. Next Steps\n1. **Write the 500-word essay** covering:\n - Dogs (characteristics, behavior, relationship with humans)\n - Cats (characteristics, behavior, relationship with humans)\n - Birds (characteristics, behavior, varieties/examples)\n - Make it detailed and well-structured\n\n2. **Call submit_analysis tool once** after the essay with comprehensive information about all three animals. Since the tool structure wasn't specified, use a logical format such as:\n - Pass information about dogs, cats, and birds as parameters\n - Could structure as JSON or separate arguments depending on tool requirements\n - Include key facts and characteristics for each animal type\n\n## 5. Context to Preserve\n- User specifically emphasized calling the tool \"only once at the end\"\n- Essay should be \"detailed\" - not just superficial information\n- Word count target is approximately 500 words\n- All three animals must be covered adequately in the essay\n- The tool call is a critical component - not optional\n" } ], "stop_reason": "end_turn", @@ -87,7 +173,7 @@ "ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0 }, - "output_tokens": 518, + "output_tokens": 525, "service_tier": "standard" } } diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f1c3350a-cdb1-4508-a208-18544b825a9e.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f1c3350a-cdb1-4508-a208-18544b825a9e.json index 7844334f..8d52e50e 100644 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f1c3350a-cdb1-4508-a208-18544b825a9e.json +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f1c3350a-cdb1-4508-a208-18544b825a9e.json @@ -1,29 +1,91 @@ [ { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "598" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What's the weather in SF in Celsius?" + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:29 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk7LXBWiTyE1QTrPLnAX", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1669", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a849d594f6bef02-AMS" + "server": "cloudflare" }, "body": { "model": "claude-haiku-4-5-20251001", - "id": "msg_01A5yigixNUyniQWth6shEDJ", + "id": "msg_01RbvNtiaJHKHJF3hmfMWMRU", "type": "message", "role": "assistant", "content": [ { "type": "tool_use", - "id": "toolu_01LqkbUvG3bxuFskR83MavPX", + "id": "toolu_01RVA12CSF1d8nekhZFR7Bcb", "name": "get_weather", "input": { "location": "San Francisco, CA", @@ -48,30 +110,116 @@ } }, { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "954" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What's the weather in SF in Celsius?" + }, + { + "role": "assistant", + "content": [ + { + "id": "toolu_01RVA12CSF1d8nekhZFR7Bcb", + "input": { + "location": "San Francisco, CA", + "units": "c" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "tool_use_id": "toolu_01RVA12CSF1d8nekhZFR7Bcb", + "content": "The weather in San Francisco, CA is currently sunny with a temperature of 20°C.", + "type": "tool_result" + } + ] + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:30 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk7Lf5mkssVqmBu1ELdx", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1270", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a849d64d8a1ef02-AMS" + "server": "cloudflare" }, "body": { "model": "claude-haiku-4-5-20251001", - "id": "msg_01K4waJ1jAaJvWS9uatX5ANU", + "id": "msg_01Mp3aR278QuTCzCTtZNHAxD", "type": "message", "role": "assistant", "content": [ { "type": "text", - "text": "The weather in San Francisco, CA is currently **sunny** with a temperature of **20°C**." + "text": "The weather in San Francisco, CA is currently **sunny** with a temperature of **20°C** (about 68°F)." } ], "stop_reason": "end_turn", @@ -84,7 +232,7 @@ "ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0 }, - "output_tokens": 24, + "output_tokens": 31, "service_tier": "standard" } } diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f27add0c-5771-4452-8ed9-996f5d74ef77.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f27add0c-5771-4452-8ed9-996f5d74ef77.json index e2740b38..462f3fa6 100644 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f27add0c-5771-4452-8ed9-996f5d74ef77.json +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/f27add0c-5771-4452-8ed9-996f5d74ef77.json @@ -1,42 +1,194 @@ [ { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "NOT_GIVEN", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper-method": "stream", + "x-stainless-stream-helper": "beta.messages", + "x-stainless-helper": "BetaToolRunner", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "602" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ], + "stream": true + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:41 GMT", "content-type": "text/event-stream; charset=utf-8", "connection": "keep-alive", - "cf-ray": "9a849daa3cc7c96e-AMS", + "server": "cloudflare", + "cf-cache-status": "DYNAMIC", "cache-control": "no-cache", - "request-id": "req_011CVk7MUVpHYeAtqMB2wjEf", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1027", - "cf-cache-status": "DYNAMIC", - "x-robots-tag": "none", - "server": "cloudflare" + "vary": "Accept-Encoding", + "x-robots-tag": "none" }, - "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_0128e4yzgSDzgbfodAq3mig6\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":3,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll look\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" up the weather in San Francisco for you\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\".\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01BxxZChiKMMRsAWwPDpTQdT\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"l\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"oca\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tion\\\": \\\"San\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Francisco\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"unit\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"s\\\": \\\"f\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":86} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" + "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_01P2vWV2BG9GRvKe41x6dini\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":26,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_014Qh2h4XRw7uSc8sXfxWQQu\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"loc\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ation\\\": \\\"San\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" Fra\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ncisco, CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"units\\\":\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\" \\\"f\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":74} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" } }, { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "NOT_GIVEN", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper-method": "stream", + "x-stainless-stream-helper": "beta.messages", + "x-stainless-helper": "BetaToolRunner", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "974" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + }, + { + "role": "assistant", + "content": [ + { + "id": "toolu_014Qh2h4XRw7uSc8sXfxWQQu", + "input": { + "location": "San Francisco, CA", + "units": "f" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_014Qh2h4XRw7uSc8sXfxWQQu", + "content": "{\"location\": \"San Francisco, CA\", \"temperature\": \"68\\u00b0F\", \"condition\": \"Sunny\"}" + } + ] + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ], + "stream": true + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:47 GMT", "content-type": "text/event-stream; charset=utf-8", "connection": "keep-alive", - "cf-ray": "9a849db43dcbc96e-AMS", + "server": "cloudflare", + "cf-cache-status": "DYNAMIC", "cache-control": "no-cache", - "request-id": "req_011CVk7MbUksXDMu1D37oqFh", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "5241", - "cf-cache-status": "DYNAMIC", - "x-robots-tag": "none", - "server": "cloudflare" + "vary": "Accept-Encoding", + "x-robots-tag": "none" }, - "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_017jipFcWV4GbthdYcheFtK8\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":782,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":6,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The weather in San Francisco,\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" CA is currently\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Sunny**\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" with a temperature of **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"68°F**\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" (about\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" 20°C).\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":782,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":32} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" + "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_01PVjGt8uRgCkDMqbEWVyv53\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":770,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" weather in San Francisco, CA is currently\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Sunny**\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" with a temperature of **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"68°F**.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":770,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":25} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" } } ] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ff848716-2309-477f-8e90-39877809aaad.json b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ff848716-2309-477f-8e90-39877809aaad.json index 7375b84b..fc9d0d2f 100644 --- a/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ff848716-2309-477f-8e90-39877809aaad.json +++ b/tests/lib/tools/__inline_snapshot__/test_runners/TestSyncRunTools/ff848716-2309-477f-8e90-39877809aaad.json @@ -1,42 +1,194 @@ [ { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "NOT_GIVEN", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper-method": "stream", + "x-stainless-stream-helper": "beta.messages", + "x-stainless-helper": "BetaToolRunner", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "602" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ], + "stream": true + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:35 GMT", "content-type": "text/event-stream; charset=utf-8", "connection": "keep-alive", - "cf-ray": "9a849d813ddb8072-AMS", + "server": "cloudflare", + "cf-cache-status": "DYNAMIC", "cache-control": "no-cache", - "request-id": "req_011CVk7LzRrjy32aXFeDdL6v", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1378", - "cf-cache-status": "DYNAMIC", - "x-robots-tag": "none", - "server": "cloudflare" + "vary": "Accept-Encoding", + "x-robots-tag": "none" }, - "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_01SAGfXDtnWyD3j4h5Wz3kky\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":26,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01LZ7WbFLVzFd16Ur9RHXeGz\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"loca\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"tion\\\": \\\"Sa\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"n Fran\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"cisco, CA\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"units\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\": \\\"f\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":74} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" + "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_01BtTXWuDXFU7AoXqmXhteHs\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":26,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01Sx7cuHYwHAkqw2MogXQQ1d\",\"name\":\"get_weather\",\"input\":{}} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"locat\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ion\\\": \\\"San F\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"rancisco\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", CA\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\", \\\"units\\\": \\\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"f\\\"}\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":656,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":74} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" } }, { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "NOT_GIVEN", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "Anthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "false", + "anthropic-version": "2023-06-01", + "x-stainless-helper-method": "stream", + "x-stainless-stream-helper": "beta.messages", + "x-stainless-helper": "BetaToolRunner", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "974" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + }, + { + "role": "assistant", + "content": [ + { + "id": "toolu_01Sx7cuHYwHAkqw2MogXQQ1d", + "input": { + "location": "San Francisco, CA", + "units": "f" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_01Sx7cuHYwHAkqw2MogXQQ1d", + "content": "{\"location\": \"San Francisco, CA\", \"temperature\": \"68\\u00b0F\", \"condition\": \"Sunny\"}" + } + ] + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ], + "stream": true + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 16:59:36 GMT", "content-type": "text/event-stream; charset=utf-8", "connection": "keep-alive", - "cf-ray": "9a849d8c5b1d8072-AMS", + "server": "cloudflare", + "cf-cache-status": "DYNAMIC", "cache-control": "no-cache", - "request-id": "req_011CVk7M8411PnGQs9cMkqBD", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1001", - "cf-cache-status": "DYNAMIC", - "x-robots-tag": "none", - "server": "cloudflare" + "vary": "Accept-Encoding", + "x-robots-tag": "none" }, - "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_01ERB2ekevEhTbZtAuM2HjmS\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":770,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":8,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The weather in San Francisco, CA is\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" currently\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"68\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"°F an\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"d Sunny**\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" \"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"☀️\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":770,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":24} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" + "body": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-haiku-4-5-20251001\",\"id\":\"msg_0112kkkttNuK7GZWAFeFrBWm\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":770,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":8,\"service_tier\":\"standard\"}} }\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"The weather in San Francisco, CA is\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" currently\"} }\n\nevent: ping\ndata: {\"type\": \"ping\"}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Sunny** with a temperature of **\"} }\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"68°F**.\"} }\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0 }\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"input_tokens\":770,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":0,\"output_tokens\":25} }\n\nevent: message_stop\ndata: {\"type\":\"message_stop\" }\n\n" } } ] \ No newline at end of file diff --git a/tests/lib/tools/__inline_snapshot__/test_runners/__module__/c4061e82-ea59-4756-9549-71a35da24499.json b/tests/lib/tools/__inline_snapshot__/test_runners/__module__/c4061e82-ea59-4756-9549-71a35da24499.json index 02591586..4ccf59c1 100644 --- a/tests/lib/tools/__inline_snapshot__/test_runners/__module__/c4061e82-ea59-4756-9549-71a35da24499.json +++ b/tests/lib/tools/__inline_snapshot__/test_runners/__module__/c4061e82-ea59-4756-9549-71a35da24499.json @@ -1,29 +1,91 @@ [ { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "AsyncAnthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "async:asyncio", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "588" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 17:23:39 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk9BQEnYiTudQzWPwnzN", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1595", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a84c0bf4b66ffef-AMS" + "server": "cloudflare" }, "body": { "model": "claude-haiku-4-5-20251001", - "id": "msg_014mVBfXF9GXKArtHjdvxo4K", + "id": "msg_01PmS112jMusZPxxKbGiWgfg", "type": "message", "role": "assistant", "content": [ { "type": "tool_use", - "id": "toolu_01V6B73Yme2e4g9zjtz2ysgG", + "id": "toolu_01UNskverbGHRXGrdU8Es5kA", "name": "get_weather", "input": { "location": "San Francisco, CA", @@ -48,30 +110,116 @@ } }, { + "request": { + "method": "POST", + "url": "https://api.anthropic.com/v1/messages?beta=true", + "headers": { + "host": "api.anthropic.com", + "accept-encoding": "gzip, deflate", + "connection": "keep-alive", + "x-stainless-timeout": "600", + "accept": "application/json", + "content-type": "application/json", + "user-agent": "AsyncAnthropic/Python 0.75.0", + "x-stainless-lang": "python", + "x-stainless-package-version": "0.75.0", + "x-stainless-os": "MacOS", + "x-stainless-arch": "arm64", + "x-stainless-runtime": "CPython", + "x-stainless-runtime-version": "3.9.18", + "x-stainless-async": "async:asyncio", + "anthropic-version": "2023-06-01", + "x-stainless-helper": "BetaToolRunner", + "anthropic-beta": "structured-outputs-2025-11-13", + "x-stainless-retry-count": "0", + "x-stainless-read-timeout": "600", + "content-length": "960" + }, + "body": { + "max_tokens": 1024, + "messages": [ + { + "role": "user", + "content": "What is the weather in SF?" + }, + { + "role": "assistant", + "content": [ + { + "id": "toolu_01UNskverbGHRXGrdU8Es5kA", + "input": { + "location": "San Francisco, CA", + "units": "f" + }, + "name": "get_weather", + "type": "tool_use" + } + ] + }, + { + "role": "user", + "content": [ + { + "type": "tool_result", + "tool_use_id": "toolu_01UNskverbGHRXGrdU8Es5kA", + "content": "{\"location\": \"San Francisco, CA\", \"temperature\": \"68\\u00b0F\", \"condition\": \"Sunny\"}" + } + ] + } + ], + "model": "claude-haiku-4-5", + "tools": [ + { + "name": "get_weather", + "description": "Lookup the weather for a given city in either celsius or fahrenheit", + "input_schema": { + "additionalProperties": false, + "properties": { + "location": { + "description": "The city and state, e.g. San Francisco, CA", + "title": "Location", + "type": "string" + }, + "units": { + "description": "Unit for the output, either 'c' for celsius or 'f' for fahrenheit", + "enum": [ + "c", + "f" + ], + "title": "Units", + "type": "string" + } + }, + "required": [ + "location", + "units" + ], + "type": "object" + } + } + ] + } + }, "response": { "status_code": 200, "headers": { - "date": "Wed, 03 Dec 2025 17:23:40 GMT", "content-type": "application/json", "connection": "keep-alive", - "request-id": "req_011CVk9BYLheDJYWkdFPeuMQ", - "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "anthropic-organization-id": "5576611f-a1ee-427c-9800-298d9579899c", - "x-envoy-upstream-service-time": "1067", "cf-cache-status": "DYNAMIC", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "vary": "Accept-Encoding", "x-robots-tag": "none", - "server": "cloudflare", - "cf-ray": "9a84c0cb2e4dffef-AMS" + "server": "cloudflare" }, "body": { "model": "claude-haiku-4-5-20251001", - "id": "msg_013CAacn66fhBYyjs4T6g4jV", + "id": "msg_01VTYCVKcYrrFfXDrjSpQRnW", "type": "message", "role": "assistant", "content": [ { "type": "text", - "text": "The weather in San Francisco, CA is currently **68°F and Sunny**. Nice weather!" + "text": "The weather in San Francisco, CA is currently **68°F and Sunny**. Great day to be outside!" } ], "stop_reason": "end_turn", @@ -84,7 +232,7 @@ "ephemeral_5m_input_tokens": 0, "ephemeral_1h_input_tokens": 0 }, - "output_tokens": 24, + "output_tokens": 27, "service_tier": "standard" } } diff --git a/tests/lib/tools/test_runners.py b/tests/lib/tools/test_runners.py index c73a9715..8b5ed903 100644 --- a/tests/lib/tools/test_runners.py +++ b/tests/lib/tools/test_runners.py @@ -58,12 +58,12 @@ def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResu ParsedBetaTextBlock( citations=None, parsed_output=None, - text='The weather in San Francisco is currently **68°F and Sunny**. Great day to be out and about!', + text='The weather in San Francisco is currently **sunny** with a temperature of **68°F** (20°C).', type='text' ) ], context_management=None, - id='msg_01FvTMNojoLmBYw4KxJXB27y', + id='msg_016diNmBsVwjnEodFdXMgg4j', model='claude-haiku-4-5-20251001', role='assistant', stop_reason='end_turn', @@ -145,7 +145,7 @@ def tool_runner(client: Anthropic) -> List[Union[BetaMessageParam, None]]: 'content': [ { 'type': 'tool_result', - 'tool_use_id': 'toolu_01Not8sU7rvvvixVRigDz1ee', + 'tool_use_id': 'toolu_01ASSujsMzFEe4PjhTGzbmdi', 'content': "RuntimeError('Unexpected error, try again')", 'is_error': True } @@ -156,10 +156,20 @@ def tool_runner(client: Anthropic) -> List[Union[BetaMessageParam, None]]: 'content': [ { 'type': 'tool_result', - 'tool_use_id': 'toolu_01LJTxn5gThzGiq5MgRfbogp', + 'tool_use_id': 'toolu_01RPpGTPHZBTK27CruspxqvL', 'content': '{"location": "San Francisco, CA", "temperature": "68\\\\u00b0F", "condition": "Sunny"}' } ] + }, + { + 'role': 'user', + 'content': [ + { + 'type': 'tool_result', + 'tool_use_id': 'toolu_014Qf7b4odsWZYj4ngf41v5R', + 'content': '{"location": "San Francisco, CA", "temperature": "20\\\\u00b0C", "condition": "Sunny"}' + } + ] } ] """ @@ -218,12 +228,12 @@ def custom_message_handling(client: Anthropic) -> BetaMessage: ParsedBetaTextBlock( citations=None, parsed_output=None, - text='The weather in San Francisco, CA is currently **sunny** with a temperature of **20°C**.', + text='The weather in San Francisco, CA is currently **sunny** with a temperature of **20°C** (about 68°F).', type='text' ) ], context_management=None, - id='msg_01K4waJ1jAaJvWS9uatX5ANU', + id='msg_01Mp3aR278QuTCzCTtZNHAxD', model='claude-haiku-4-5-20251001', role='assistant', stop_reason='end_turn', @@ -234,7 +244,7 @@ def custom_message_handling(client: Anthropic) -> BetaMessage: cache_creation_input_tokens=0, cache_read_input_tokens=0, input_tokens=763, - output_tokens=24, + output_tokens=31, server_tool_use=None, service_tier='standard' ) @@ -321,12 +331,12 @@ def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResu ParsedBetaTextBlock( citations=None, parsed_output=None, - text='The weather in San Francisco, CA is currently **68°F and Sunny** ☀️', + text='The weather in San Francisco, CA is currently **Sunny** with a temperature of **68°F**.', type='text' ) ], context_management=None, - id='msg_01ERB2ekevEhTbZtAuM2HjmS', + id='msg_0112kkkttNuK7GZWAFeFrBWm', model='claude-haiku-4-5-20251001', role='assistant', stop_reason='end_turn', @@ -337,7 +347,7 @@ def get_weather(location: str, units: Literal["c", "f"]) -> BetaFunctionToolResu cache_creation_input_tokens=0, cache_read_input_tokens=0, input_tokens=770, - output_tokens=24, + output_tokens=25, server_tool_use=None, service_tier='standard' ) @@ -398,7 +408,7 @@ def get_weather_answers(client: Anthropic) -> List[Union[BetaMessageParam, None] 'content': [ { 'type': 'tool_result', - 'tool_use_id': 'toolu_01FpmqujJtkj11RDCJySJWUH', + 'tool_use_id': 'toolu_01DUC5sKZofEcuFX4NTvXAGp', 'content': '{"location": "San Francisco, CA", "temperature": "68\\\\u00b0F", "condition": "Sunny"}' } ] @@ -408,7 +418,7 @@ def get_weather_answers(client: Anthropic) -> List[Union[BetaMessageParam, None] 'content': [ { 'type': 'tool_result', - 'tool_use_id': 'toolu_017cDHUBfAhBDseR2vW7axod', + 'tool_use_id': 'toolu_01B3V3NpBkEHenKXsgAW7mhQ', 'content': '{"location": "New York, NY", "temperature": "68\\\\u00b0F", "condition": "Sunny"}' } ] @@ -513,57 +523,46 @@ def tool_runner(client: Anthropic) -> BetaToolRunner[None]: assert content["text"] == snapshot("""\ ## 1. Task Overview -The user has requested: -- Write a detailed 500-word essay about dogs, cats, and birds -- Call the tool `submit_analysis` ONCE at the end with information about all three animals -- The tool should contain compiled information from the essay about all three animal types - -Success criteria: +The user requested a detailed 500-word essay about dogs, cats, and birds, followed by a single call to a tool named `submit_analysis` with information about all three animals. Key requirements: - Essay must be approximately 500 words -- Must cover all three animals (dogs, cats, birds) -- Must be detailed -- Single tool call at the very end containing analysis/information about all three animals +- Must cover all three animal types: dogs, cats, and birds +- Must call `submit_analysis` tool exactly once at the end +- The tool call should contain information about all three animals ## 2. Current State -**Completed:** Nothing has been completed yet. - -**Files/Outputs:** None created. +**Completed:** Nothing has been completed yet. This appears to be the initial state of the task. -**Status:** Task not started. No essay has been written, and no tool has been called. +**Not yet done:** +- The 500-word essay has not been written +- The `submit_analysis` tool has not been called ## 3. Important Discoveries -No technical constraints have been uncovered yet, as work hasn't begun. +**Constraints identified:** +- The tool `submit_analysis` must be called only once, not separately for each animal +- The tool call should occur after the essay is complete +- Need to determine the proper parameters/format for `submit_analysis` tool (this information was not provided in the initial request) -**Key requirements identified:** -- Need to understand the `submit_analysis` tool parameters (what fields it accepts) -- The tool call should synthesize information about all three animals from the essay -- Only ONE tool call should be made, despite covering three different animals +**Uncertainty:** +- The exact structure and parameters expected by `submit_analysis` are unclear. Will need to infer or use reasonable structure when calling the tool (e.g., might expect JSON with animal names and their characteristics, or separate parameters for each animal) ## 4. Next Steps -**Immediate actions required:** - 1. **Write the 500-word essay** covering: - - Dogs (characteristics, behavior, role as pets, etc.) - - Cats (characteristics, behavior, role as pets, etc.) - - Birds (characteristics, behavior, role as pets, etc.) - - Ensure balanced coverage of all three animals - - Aim for approximately 500 words total - -2. **Call `submit_analysis` tool once** after completing the essay: - - Structure the tool call to include information about all three animals - - Likely format: summarize key points about each animal type - - May need to check tool schema to understand expected parameters - -**Priority:** Write essay first, then make single tool call. + - Dogs (characteristics, behavior, relationship with humans) + - Cats (characteristics, behavior, relationship with humans) + - Birds (characteristics, behavior, varieties/examples) + - Make it detailed and well-structured -**Blockers/Questions:** \n\ -- Need to determine exact parameters for `submit_analysis` tool when ready to call it +2. **Call submit_analysis tool once** after the essay with comprehensive information about all three animals. Since the tool structure wasn't specified, use a logical format such as: + - Pass information about dogs, cats, and birds as parameters + - Could structure as JSON or separate arguments depending on tool requirements + - Include key facts and characteristics for each animal type ## 5. Context to Preserve - User specifically emphasized calling the tool "only once at the end" -- Essay should be "detailed" - aim for substantive content, not superficial -- All three animals must be covered adequately -- Word count target: approximately 500 words +- Essay should be "detailed" - not just superficial information +- Word count target is approximately 500 words +- All three animals must be covered adequately in the essay +- The tool call is a critical component - not optional \ """) assert caplog.record_tuples == snapshot( @@ -571,9 +570,9 @@ def tool_runner(client: Anthropic) -> BetaToolRunner[None]: ( "anthropic.lib.tools._beta_runner", 20, - "Token usage 1663 has exceeded the threshold of 500. Performing compaction.", + "Token usage 1609 has exceeded the threshold of 500. Performing compaction.", ), - ("anthropic.lib.tools._beta_runner", 20, "Compaction complete. New token usage: 518"), + ("anthropic.lib.tools._beta_runner", 20, "Compaction complete. New token usage: 525"), ] ) diff --git a/uv.lock b/uv.lock index 879b4eed..c9c0807d 100644 --- a/uv.lock +++ b/uv.lock @@ -263,7 +263,7 @@ dev = [ { name = "boto3-stubs", specifier = ">=1" }, { name = "dirty-equals", specifier = ">=0.6.0" }, { name = "griffe", specifier = ">=1" }, - { name = "http-snapshot", extras = ["httpx"], specifier = "==0.1.4" }, + { name = "http-snapshot", extras = ["httpx"], specifier = "==0.1.5" }, { name = "importlib-metadata", specifier = ">=6.7.0" }, { name = "inline-snapshot", specifier = ">=0.28.0" }, { name = "mypy", specifier = "==1.17" }, @@ -755,14 +755,14 @@ wheels = [ [[package]] name = "http-snapshot" -version = "0.1.4" +version = "0.1.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "inline-snapshot" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/97/5f/8fc01489d3857642c801a4598aa47a64a3ddb4e4b397b8ba0ead9e1eb6ca/http_snapshot-0.1.4.tar.gz", hash = "sha256:e51d021e82e61eaacda15448fb58f98e088480de428cc13dd77049760f12c969", size = 10752, upload-time = "2025-12-03T13:36:02.79Z" } +sdist = { url = "https://files.pythonhosted.org/packages/91/31/0f689657847032261ad4efcaa202d7e9cacf97baba3b28e32f8b67621cdf/http_snapshot-0.1.5.tar.gz", hash = "sha256:8af9025dbc87b2325f0d1bbed853e82f961872a59792fc00d7bf1621b6334812", size = 10803, upload-time = "2025-12-16T09:22:28.141Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/36/a8/c1552b6758d0991b547b6a691408282374f86dea441f82b40a7cf8e13dfa/http_snapshot-0.1.4-py3-none-any.whl", hash = "sha256:ee642c5ff36a01bdfe525c125786584ea3fe26f952a44022648db2d6ff03a845", size = 11429, upload-time = "2025-12-03T13:36:01.527Z" }, + { url = "https://files.pythonhosted.org/packages/bb/d4/d8bf5ad9491f677c04644ee8d298bbc6adcc16a5ba907792b45cdd40912c/http_snapshot-0.1.5-py3-none-any.whl", hash = "sha256:6db9d8c58f97365d0ccadbae7fc7a1ff90438a02aa83331c312723a2c32b1373", size = 11490, upload-time = "2025-12-16T09:22:27.167Z" }, ] [package.optional-dependencies] From 4d1813df0517feffa05d70202747c6f21c46a581 Mon Sep 17 00:00:00 2001 From: karpetrosyan Date: Tue, 16 Dec 2025 14:20:04 +0400 Subject: [PATCH 8/8] bump http-snapshot version --- pyproject.toml | 2 +- uv.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ba8d5c0d..39a3971b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -74,7 +74,7 @@ dev = [ "pytest-xdist>=3.6.1", "inline-snapshot>=0.28.0", "griffe>=1", - "http-snapshot[httpx]==0.1.5", + "http-snapshot[httpx]==0.1.6", ] pydantic-v1 = [ "pydantic>=1.9.0,<2", diff --git a/uv.lock b/uv.lock index c9c0807d..f0774156 100644 --- a/uv.lock +++ b/uv.lock @@ -263,7 +263,7 @@ dev = [ { name = "boto3-stubs", specifier = ">=1" }, { name = "dirty-equals", specifier = ">=0.6.0" }, { name = "griffe", specifier = ">=1" }, - { name = "http-snapshot", extras = ["httpx"], specifier = "==0.1.5" }, + { name = "http-snapshot", extras = ["httpx"], specifier = "==0.1.6" }, { name = "importlib-metadata", specifier = ">=6.7.0" }, { name = "inline-snapshot", specifier = ">=0.28.0" }, { name = "mypy", specifier = "==1.17" }, @@ -755,14 +755,14 @@ wheels = [ [[package]] name = "http-snapshot" -version = "0.1.5" +version = "0.1.6" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "inline-snapshot" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/91/31/0f689657847032261ad4efcaa202d7e9cacf97baba3b28e32f8b67621cdf/http_snapshot-0.1.5.tar.gz", hash = "sha256:8af9025dbc87b2325f0d1bbed853e82f961872a59792fc00d7bf1621b6334812", size = 10803, upload-time = "2025-12-16T09:22:28.141Z" } +sdist = { url = "https://files.pythonhosted.org/packages/41/a7/c94382d2b1bad33f9e7ac34048e0784be78f21c31693e8b354eec72a261a/http_snapshot-0.1.6.tar.gz", hash = "sha256:16b1cc04645e84b5d225ba272b3df4a29bbdb84386087e8435806299a7895a5d", size = 10835, upload-time = "2025-12-16T10:12:03.162Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bb/d4/d8bf5ad9491f677c04644ee8d298bbc6adcc16a5ba907792b45cdd40912c/http_snapshot-0.1.5-py3-none-any.whl", hash = "sha256:6db9d8c58f97365d0ccadbae7fc7a1ff90438a02aa83331c312723a2c32b1373", size = 11490, upload-time = "2025-12-16T09:22:27.167Z" }, + { url = "https://files.pythonhosted.org/packages/5b/43/749861077584bd35c73482d38f625cd349efc6a5ec6f03ab8768ed5a6432/http_snapshot-0.1.6-py3-none-any.whl", hash = "sha256:a79adc33f840643750a5ecbd55988ebc009097d962af71857924aafcc16c086a", size = 11626, upload-time = "2025-12-16T10:12:01.823Z" }, ] [package.optional-dependencies]