Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion examples/memory/basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,7 +376,7 @@ def conversation_loop():
messages.append({"role": "assistant", "content": assistant_content})

# Generate tool response automatically
tool_response = runner.generate_tool_call_response()
tool_response = runner.generate_tool_response()
if tool_response and tool_response["content"]:
# Add tool results to messages
messages.append({"role": "user", "content": tool_response["content"]})
Expand Down
46 changes: 41 additions & 5 deletions src/anthropic/lib/tools/_beta_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
AsyncIterator,
)
from contextlib import contextmanager, asynccontextmanager
from typing_extensions import TypedDict, override
from typing_extensions import TypedDict, override, deprecated

import httpx

Expand Down Expand Up @@ -250,7 +250,7 @@ def __run__(self) -> Iterator[RunnerItemT]:

# If the compaction was performed, skip tool call generation this iteration
if not self._check_and_compact():
response = self.generate_tool_call_response()
response = self.generate_tool_response()
if response is None:
log.debug("Tool call was not requested, exiting from tool runner loop.")
return
Expand All @@ -271,7 +271,7 @@ def until_done(self) -> ParsedBetaMessage[ResponseFormatT]:
assert last_message is not None
return last_message

def generate_tool_call_response(self) -> BetaMessageParam | None:
def generate_tool_response(self) -> BetaMessageParam | None:
"""Generate a MessageParam by calling tool functions with any tool use blocks from the last message.

Note the tool call response is cached, repeated calls to this method will return the same response.
Expand All @@ -285,6 +285,24 @@ def generate_tool_call_response(self) -> BetaMessageParam | None:
self._cached_tool_call_response = response
return response

@deprecated("generate_tool_call_response is deprecated, use generate_tool_response instead")
def generate_tool_call_response(self) -> BetaMessageParam | None:
"""Generate a MessageParam by calling tool functions with any tool use blocks from the last message.

.. deprecated::
Use :meth:`generate_tool_response` instead.

Note the tool call response is cached, repeated calls to this method will return the same response.

None can be returned if no tool call was applicable.
"""
warnings.warn(
"generate_tool_call_response is deprecated, use generate_tool_response instead",
DeprecationWarning,
stacklevel=2,
)
return self.generate_tool_response()

def _generate_tool_call_response(self) -> BetaMessageParam | None:
content = self._get_last_assistant_message_content()
if not content:
Expand Down Expand Up @@ -501,7 +519,7 @@ async def __run__(self) -> AsyncIterator[RunnerItemT]:

# If the compaction was performed, skip tool call generation this iteration
if not await self._check_and_compact():
response = await self.generate_tool_call_response()
response = await self.generate_tool_response()
if response is None:
log.debug("Tool call was not requested, exiting from tool runner loop.")
return
Expand All @@ -522,7 +540,7 @@ async def until_done(self) -> ParsedBetaMessage[ResponseFormatT]:
assert last_message is not None
return last_message

async def generate_tool_call_response(self) -> BetaMessageParam | None:
async def generate_tool_response(self) -> BetaMessageParam | None:
"""Generate a MessageParam by calling tool functions with any tool use blocks from the last message.

Note the tool call response is cached, repeated calls to this method will return the same response.
Expand All @@ -537,6 +555,24 @@ async def generate_tool_call_response(self) -> BetaMessageParam | None:
self._cached_tool_call_response = response
return response

@deprecated("generate_tool_call_response is deprecated, use generate_tool_response instead")
async def generate_tool_call_response(self) -> BetaMessageParam | None:
"""Generate a MessageParam by calling tool functions with any tool use blocks from the last message.

.. deprecated::
Use :meth:`generate_tool_response` instead.

Note the tool call response is cached, repeated calls to this method will return the same response.

None can be returned if no tool call was applicable.
"""
warnings.warn(
"generate_tool_call_response is deprecated, use generate_tool_response instead",
DeprecationWarning,
stacklevel=2,
)
return await self.generate_tool_response()

async def _get_last_message(self) -> ParsedBetaMessage[ResponseFormatT] | None:
if callable(self._last_message):
return await self._last_message()
Expand Down
32 changes: 28 additions & 4 deletions tests/lib/tools/test_runners.py
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ def tool_runner(client: Anthropic) -> List[Union[BetaMessageParam, None]]:

actual_responses: List[Union[BetaMessageParam, None]] = []
for _ in runner:
tool_call_response = runner.generate_tool_call_response()
tool_call_response = runner.generate_tool_response()
if tool_call_response is not None:
actual_responses.append(tool_call_response)

Expand Down Expand Up @@ -250,8 +250,8 @@ def tool_runner(client: Anthropic) -> None:
)

for _ in runner:
response1 = runner.generate_tool_call_response()
response2 = runner.generate_tool_call_response()
response1 = runner.generate_tool_response()
response2 = runner.generate_tool_response()

if response1 is not None:
assert response1 is response2
Expand Down Expand Up @@ -331,7 +331,7 @@ def get_weather_answers(client: Anthropic) -> List[Union[BetaMessageParam, None]
answers: List[Union[BetaMessageParam, None]] = []

for _ in runner:
answers.append(runner.generate_tool_call_response())
answers.append(runner.generate_tool_response())

return answers

Expand Down Expand Up @@ -613,3 +613,27 @@ def test_tool_runner_method_in_sync(sync: bool, client: Anthropic, async_client:
"stream",
},
)


def test_generate_tool_call_response_deprecated(client: Anthropic) -> None:
runner = client.beta.messages.tool_runner(
model="claude-haiku-4-5",
messages=[{"role": "user", "content": "What's the weather in SF in Celsius?"}],
tools=[],
max_tokens=1024,
)

with pytest.deprecated_call():
runner.generate_tool_call_response() # type: ignore[reportDeprecated]


async def test_generate_tool_call_response_deprecated_async(async_client: AsyncAnthropic) -> None:
runner = async_client.beta.messages.tool_runner(
model="claude-haiku-4-5",
messages=[{"role": "user", "content": "What's the weather in SF in Celsius?"}],
tools=[],
max_tokens=1024,
)

with pytest.deprecated_call():
await runner.generate_tool_call_response() # type: ignore[reportDeprecated]