BaseSyncToolRunner Class — anthropic-sdk-python Architecture
Architecture documentation for the BaseSyncToolRunner class in _beta_runner.py from the anthropic-sdk-python codebase.
Entity Profile
Dependency Diagram
graph TD 9149fa46_e498_7ba3_1b94_e0095e473ff9["BaseSyncToolRunner"] 34260b96_4096_ba59_bee2_0b2a94476dcc["_beta_runner.py"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|defined in| 34260b96_4096_ba59_bee2_0b2a94476dcc dd434c66_6da1_43c9_3951_9997ee2b51e1["__init__()"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|method| dd434c66_6da1_43c9_3951_9997ee2b51e1 694c5c25_1fd1_eba8_9d46_bb06933e777e["__next__()"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|method| 694c5c25_1fd1_eba8_9d46_bb06933e777e cbb91a73_95d7_b16b_fa55_3827abab7e91["__iter__()"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|method| cbb91a73_95d7_b16b_fa55_3827abab7e91 7a42b7b5_3b45_98bf_0780_6f0ec5133610["_handle_request()"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|method| 7a42b7b5_3b45_98bf_0780_6f0ec5133610 fc3214ad_dd7a_b1a4_994d_95d55d1f3a68["_check_and_compact()"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|method| fc3214ad_dd7a_b1a4_994d_95d55d1f3a68 98b55090_3b6f_2dd4_ca2d_6c52114d5a9e["__run__()"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|method| 98b55090_3b6f_2dd4_ca2d_6c52114d5a9e 1da9fb48_10a6_0c76_a1ce_2ab027e77a58["until_done()"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|method| 1da9fb48_10a6_0c76_a1ce_2ab027e77a58 b6f147a7_041c_a75b_75d3_8d273a48e4e5["generate_tool_call_response()"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|method| b6f147a7_041c_a75b_75d3_8d273a48e4e5 d1f2e83f_ca29_2f3a_83b4_5a5af4a46b73["_generate_tool_call_response()"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|method| d1f2e83f_ca29_2f3a_83b4_5a5af4a46b73 b2a98d76_24b2_7388_d54b_d0f7084fdb5f["_get_last_message()"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|method| b2a98d76_24b2_7388_d54b_d0f7084fdb5f b4a3f0c6_055a_0af4_1a49_fa0d3d9a7923["_get_last_assistant_message_content()"] 9149fa46_e498_7ba3_1b94_e0095e473ff9 -->|method| b4a3f0c6_055a_0af4_1a49_fa0d3d9a7923
Relationship Graph
Source Code
src/anthropic/lib/tools/_beta_runner.py lines 120–346
class BaseSyncToolRunner(BaseToolRunner[BetaRunnableTool, ResponseFormatT], Generic[RunnerItemT, ResponseFormatT], ABC):
def __init__(
self,
*,
params: ParseMessageCreateParamsBase[ResponseFormatT],
options: RequestOptions,
tools: Iterable[BetaRunnableTool],
client: Anthropic,
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[[], ParsedBetaMessage[ResponseFormatT]] | ParsedBetaMessage[ResponseFormatT] | None
) = None
def __next__(self) -> RunnerItemT:
return self._iterator.__next__()
def __iter__(self) -> Iterator[RunnerItemT]:
for item in self._iterator:
yield item
@abstractmethod
@contextmanager
def _handle_request(self) -> Iterator[RunnerItemT]:
raise NotImplementedError()
yield # type: ignore[unreachable]
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 = 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"
]
if non_tool_blocks:
messages[-1]["content"] = non_tool_blocks
else:
messages.pop()
Domain
Defined In
Source
Frequently Asked Questions
What is the BaseSyncToolRunner class?
BaseSyncToolRunner is a class in the anthropic-sdk-python codebase, defined in src/anthropic/lib/tools/_beta_runner.py.
Where is BaseSyncToolRunner defined?
BaseSyncToolRunner is defined in src/anthropic/lib/tools/_beta_runner.py at line 120.
Analyze Your Own Codebase
Get architecture documentation, dependency graphs, and domain analysis for your codebase in minutes.
Try Supermodel Free