Skip to content

Commit 1521316

Browse files
authored
feat(tool runner): add support for server-side tools (#1086)
1 parent 2163d26 commit 1521316

File tree

4 files changed

+95
-15
lines changed

4 files changed

+95
-15
lines changed

src/anthropic/lib/tools/_beta_runner.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from __future__ import annotations
22

33
import logging
4+
import warnings
45
from abc import ABC, abstractmethod
56
from typing import (
67
TYPE_CHECKING,
@@ -298,6 +299,14 @@ def _generate_tool_call_response(self) -> BetaMessageParam | None:
298299
for tool_use in tool_use_blocks:
299300
tool = self._tools_by_name.get(tool_use.name)
300301
if tool is None:
302+
warnings.warn(
303+
f"Tool '{tool_use.name}' not found in tool runner. "
304+
f"Available tools: {list(self._tools_by_name.keys())}. "
305+
f"If using a raw tool definition, handle the tool call manually and use `append_messages()` to add the result. "
306+
f"Otherwise, pass the tool using `beta_tool(func)` or a `@beta_tool` decorated function.",
307+
UserWarning,
308+
stacklevel=3,
309+
)
301310
results.append(
302311
{
303312
"type": "tool_result",
@@ -554,6 +563,14 @@ async def _generate_tool_call_response(self) -> BetaMessageParam | None:
554563
for tool_use in tool_use_blocks:
555564
tool = self._tools_by_name.get(tool_use.name)
556565
if tool is None:
566+
warnings.warn(
567+
f"Tool '{tool_use.name}' not found in tool runner. "
568+
f"Available tools: {list(self._tools_by_name.keys())}. "
569+
f"If using a raw tool definition, handle the tool call manually and use `append_messages()` to add the result. "
570+
f"Otherwise, pass the tool using `beta_async_tool(func)` or a `@beta_async_tool` decorated function.",
571+
UserWarning,
572+
stacklevel=3,
573+
)
557574
results.append(
558575
{
559576
"type": "tool_result",

src/anthropic/resources/beta/messages/messages.py

Lines changed: 40 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,14 @@
4848
from ....lib._parse._response import ResponseFormatT, parse_response
4949
from ....lib._parse._transform import transform_schema
5050
from ....types.beta.beta_message import BetaMessage
51-
from ....lib.tools._beta_functions import BetaRunnableTool, BetaAsyncRunnableTool
51+
from ....lib.tools._beta_functions import (
52+
BetaFunctionTool,
53+
BetaRunnableTool,
54+
BetaAsyncFunctionTool,
55+
BetaAsyncRunnableTool,
56+
BetaBuiltinFunctionTool,
57+
BetaAsyncBuiltinFunctionTool,
58+
)
5259
from ....types.anthropic_beta_param import AnthropicBetaParam
5360
from ....types.beta.beta_message_param import BetaMessageParam
5461
from ....types.beta.beta_metadata_param import BetaMetadataParam
@@ -1175,7 +1182,7 @@ def tool_runner(
11751182
max_tokens: int,
11761183
messages: Iterable[BetaMessageParam],
11771184
model: ModelParam,
1178-
tools: Iterable[BetaRunnableTool],
1185+
tools: Iterable[BetaRunnableTool | BetaToolUnionParam],
11791186
compaction_control: CompactionControl | Omit = omit,
11801187
container: Optional[message_create_params.Container] | Omit = omit,
11811188
context_management: Optional[BetaContextManagementConfigParam] | Omit = omit,
@@ -1209,7 +1216,7 @@ def tool_runner(
12091216
max_tokens: int,
12101217
messages: Iterable[BetaMessageParam],
12111218
model: ModelParam,
1212-
tools: Iterable[BetaRunnableTool],
1219+
tools: Iterable[BetaRunnableTool | BetaToolUnionParam],
12131220
compaction_control: CompactionControl | Omit = omit,
12141221
stream: Literal[True],
12151222
max_iterations: int | Omit = omit,
@@ -1243,7 +1250,7 @@ def tool_runner(
12431250
max_tokens: int,
12441251
messages: Iterable[BetaMessageParam],
12451252
model: ModelParam,
1246-
tools: Iterable[BetaRunnableTool],
1253+
tools: Iterable[BetaRunnableTool | BetaToolUnionParam],
12471254
compaction_control: CompactionControl | Omit = omit,
12481255
stream: bool,
12491256
max_iterations: int | Omit = omit,
@@ -1276,7 +1283,7 @@ def tool_runner(
12761283
max_tokens: int,
12771284
messages: Iterable[BetaMessageParam],
12781285
model: ModelParam,
1279-
tools: Iterable[BetaRunnableTool],
1286+
tools: Iterable[BetaRunnableTool | BetaToolUnionParam],
12801287
compaction_control: CompactionControl | Omit = omit,
12811288
max_iterations: int | Omit = omit,
12821289
container: Optional[message_create_params.Container] | Omit = omit,
@@ -1316,6 +1323,15 @@ def tool_runner(
13161323
**(extra_headers or {}),
13171324
}
13181325

1326+
runnable_tools: list[BetaRunnableTool] = []
1327+
raw_tools: list[BetaToolUnionParam] = []
1328+
1329+
for tool in tools:
1330+
if isinstance(tool, (BetaFunctionTool, BetaBuiltinFunctionTool)):
1331+
runnable_tools.append(tool)
1332+
else:
1333+
raw_tools.append(tool)
1334+
13191335
params = cast(
13201336
message_create_params.ParseMessageCreateParamsBase[ResponseFormatT],
13211337
{
@@ -1334,15 +1350,15 @@ def tool_runner(
13341350
"temperature": temperature,
13351351
"thinking": thinking,
13361352
"tool_choice": tool_choice,
1337-
"tools": [tool.to_dict() for tool in tools],
1353+
"tools": [*[tool.to_dict() for tool in runnable_tools], *raw_tools],
13381354
"top_k": top_k,
13391355
"top_p": top_p,
13401356
},
13411357
)
13421358

13431359
if stream:
13441360
return BetaStreamingToolRunner[ResponseFormatT](
1345-
tools=tools,
1361+
tools=runnable_tools,
13461362
params=params,
13471363
options={
13481364
"extra_headers": extra_headers,
@@ -1355,7 +1371,7 @@ def tool_runner(
13551371
compaction_control=compaction_control if is_given(compaction_control) else None,
13561372
)
13571373
return BetaToolRunner[ResponseFormatT](
1358-
tools=tools,
1374+
tools=runnable_tools,
13591375
params=params,
13601376
options={
13611377
"extra_headers": extra_headers,
@@ -2826,7 +2842,7 @@ def tool_runner(
28262842
max_tokens: int,
28272843
messages: Iterable[BetaMessageParam],
28282844
model: ModelParam,
2829-
tools: Iterable[BetaAsyncRunnableTool],
2845+
tools: Iterable[BetaAsyncRunnableTool | BetaToolUnionParam],
28302846
compaction_control: CompactionControl | Omit = omit,
28312847
max_iterations: int | Omit = omit,
28322848
container: Optional[message_create_params.Container] | Omit = omit,
@@ -2860,7 +2876,7 @@ def tool_runner(
28602876
max_tokens: int,
28612877
messages: Iterable[BetaMessageParam],
28622878
model: ModelParam,
2863-
tools: Iterable[BetaAsyncRunnableTool],
2879+
tools: Iterable[BetaAsyncRunnableTool | BetaToolUnionParam],
28642880
compaction_control: CompactionControl | Omit = omit,
28652881
stream: Literal[True],
28662882
max_iterations: int | Omit = omit,
@@ -2894,7 +2910,7 @@ def tool_runner(
28942910
max_tokens: int,
28952911
messages: Iterable[BetaMessageParam],
28962912
model: ModelParam,
2897-
tools: Iterable[BetaAsyncRunnableTool],
2913+
tools: Iterable[BetaAsyncRunnableTool | BetaToolUnionParam],
28982914
compaction_control: CompactionControl | Omit = omit,
28992915
stream: bool,
29002916
max_iterations: int | Omit = omit,
@@ -2927,7 +2943,7 @@ def tool_runner(
29272943
max_tokens: int,
29282944
messages: Iterable[BetaMessageParam],
29292945
model: ModelParam,
2930-
tools: Iterable[BetaAsyncRunnableTool],
2946+
tools: Iterable[BetaAsyncRunnableTool | BetaToolUnionParam],
29312947
compaction_control: CompactionControl | Omit = omit,
29322948
max_iterations: int | Omit = omit,
29332949
container: Optional[message_create_params.Container] | Omit = omit,
@@ -2967,6 +2983,15 @@ def tool_runner(
29672983
**(extra_headers or {}),
29682984
}
29692985

2986+
runnable_tools: list[BetaAsyncRunnableTool] = []
2987+
raw_tools: list[BetaToolUnionParam] = []
2988+
2989+
for tool in tools:
2990+
if isinstance(tool, (BetaAsyncFunctionTool, BetaAsyncBuiltinFunctionTool)):
2991+
runnable_tools.append(tool)
2992+
else:
2993+
raw_tools.append(tool)
2994+
29702995
params = cast(
29712996
message_create_params.ParseMessageCreateParamsBase[ResponseFormatT],
29722997
{
@@ -2985,15 +3010,15 @@ def tool_runner(
29853010
"temperature": temperature,
29863011
"thinking": thinking,
29873012
"tool_choice": tool_choice,
2988-
"tools": [tool.to_dict() for tool in tools],
3013+
"tools": [*[tool.to_dict() for tool in runnable_tools], *raw_tools],
29893014
"top_k": top_k,
29903015
"top_p": top_p,
29913016
},
29923017
)
29933018

29943019
if stream:
29953020
return BetaAsyncStreamingToolRunner[ResponseFormatT](
2996-
tools=tools,
3021+
tools=runnable_tools,
29973022
params=params,
29983023
options={
29993024
"extra_headers": extra_headers,
@@ -3006,7 +3031,7 @@ def tool_runner(
30063031
compaction_control=compaction_control if is_given(compaction_control) else None,
30073032
)
30083033
return BetaAsyncToolRunner[ResponseFormatT](
3009-
tools=tools,
3034+
tools=runnable_tools,
30103035
params=params,
30113036
options={
30123037
"extra_headers": extra_headers,

0 commit comments

Comments
 (0)