BaseAsyncToolRunner Class — anthropic-sdk-python Architecture
Architecture documentation for the BaseAsyncToolRunner class in _beta_runner.py from the anthropic-sdk-python codebase.
Entity Profile
Dependency Diagram
graph TD e1032e12_8173_7783_f9c6_c9b9260e5366["BaseAsyncToolRunner"] 34260b96_4096_ba59_bee2_0b2a94476dcc["_beta_runner.py"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|defined in| 34260b96_4096_ba59_bee2_0b2a94476dcc 53239ab2_c71e_0ab2_e526_c17e041df495["__init__()"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|method| 53239ab2_c71e_0ab2_e526_c17e041df495 a04746df_b1da_02ff_7b8c_770712a39fc8["__anext__()"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|method| a04746df_b1da_02ff_7b8c_770712a39fc8 0cd46b4e_5294_2b5b_2fed_87c20a5541ed["__aiter__()"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|method| 0cd46b4e_5294_2b5b_2fed_87c20a5541ed 947ff695_bb6a_d258_a971_760cc41d22a6["_handle_request()"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|method| 947ff695_bb6a_d258_a971_760cc41d22a6 dc62d390_be42_9d71_fa80_f161d7ae3cc8["_check_and_compact()"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|method| dc62d390_be42_9d71_fa80_f161d7ae3cc8 e767db6b_72ea_d60e_0f49_54ac2dd6c0a7["__run__()"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|method| e767db6b_72ea_d60e_0f49_54ac2dd6c0a7 0a6c0591_45c9_6f1d_0ff2_febf24cf88b5["until_done()"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|method| 0a6c0591_45c9_6f1d_0ff2_febf24cf88b5 e6eb0ae3_dad5_13a8_e981_1b176438b0fe["generate_tool_call_response()"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|method| e6eb0ae3_dad5_13a8_e981_1b176438b0fe 1fdee5f9_923d_e71a_5610_d1556341274b["_get_last_message()"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|method| 1fdee5f9_923d_e71a_5610_d1556341274b f070b824_7b1c_09b2_23ba_84bb23647a08["_get_last_assistant_message_content()"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|method| f070b824_7b1c_09b2_23ba_84bb23647a08 b5b59a19_0646_9f18_1716_6cbb729f18af["_generate_tool_call_response()"] e1032e12_8173_7783_f9c6_c9b9260e5366 -->|method| b5b59a19_0646_9f18_1716_6cbb729f18af
Relationship Graph
Source Code
src/anthropic/lib/tools/_beta_runner.py lines 367–598
class BaseAsyncToolRunner(
BaseToolRunner[BetaAsyncRunnableTool, ResponseFormatT], Generic[RunnerItemT, ResponseFormatT], ABC
):
def __init__(
self,
*,
params: ParseMessageCreateParamsBase[ResponseFormatT],
options: RequestOptions,
tools: Iterable[BetaAsyncRunnableTool],
client: AsyncAnthropic,
max_iterations: int | None = None,
compaction_control: CompactionControl | None = None,
) -> None:
super().__init__(
params=params,
options=options,
tools=tools,
max_iterations=max_iterations,
compaction_control=compaction_control,
)
self._client = client
self._iterator = self.__run__()
self._last_message: (
Callable[[], Coroutine[None, None, ParsedBetaMessage[ResponseFormatT]]]
| ParsedBetaMessage[ResponseFormatT]
| None
) = None
async def __anext__(self) -> RunnerItemT:
return await self._iterator.__anext__()
async def __aiter__(self) -> AsyncIterator[RunnerItemT]:
async for item in self._iterator:
yield item
@abstractmethod
@asynccontextmanager
async def _handle_request(self) -> AsyncIterator[RunnerItemT]:
raise NotImplementedError()
yield # type: ignore[unreachable]
async def _check_and_compact(self) -> bool:
"""
Check token usage and compact messages if threshold exceeded.
Returns True if compaction was performed, False otherwise.
"""
if self._compaction_control is None or not self._compaction_control["enabled"]:
return False
message = await self._get_last_message()
tokens_used = 0
if message is not None:
total_input_tokens = (
message.usage.input_tokens
+ (message.usage.cache_creation_input_tokens or 0)
+ (message.usage.cache_read_input_tokens or 0)
)
tokens_used = total_input_tokens + message.usage.output_tokens
threshold = self._compaction_control.get("context_token_threshold", DEFAULT_THRESHOLD)
if tokens_used < threshold:
return False
# Perform compaction
log.info(f"Token usage {tokens_used} has exceeded the threshold of {threshold}. Performing compaction.")
model = self._compaction_control.get("model", self._params["model"])
messages = list(self._params["messages"])
if messages[-1]["role"] == "assistant":
# Remove tool_use blocks from the last message to avoid 400 error
# (tool_use requires tool_result, which we don't have yet)
non_tool_blocks = [
block
for block in messages[-1]["content"]
if isinstance(block, dict) and block.get("type") != "tool_use"
]
Domain
Defined In
Source
Frequently Asked Questions
What is the BaseAsyncToolRunner class?
BaseAsyncToolRunner is a class in the anthropic-sdk-python codebase, defined in src/anthropic/lib/tools/_beta_runner.py.
Where is BaseAsyncToolRunner defined?
BaseAsyncToolRunner is defined in src/anthropic/lib/tools/_beta_runner.py at line 367.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free