Add enable_tools, enabled_tools, session_id to /v1/messages endpoint
Support the same shorthand as /v1/chat/completions: enable_tools=true with an optional enabled_tools list uses built-in server tools without requiring full Anthropic tool definitions. session_id is passed through for sandbox isolation. max_tokens is now optional.
This commit is contained in:
parent
ae6cbc59f0
commit
bb1ac77c34
3 changed files with 48 additions and 8 deletions
|
|
@ -621,7 +621,7 @@ class AnthropicTool(BaseModel):
|
|||
|
||||
class AnthropicMessagesRequest(BaseModel):
|
||||
model: str = "default"
|
||||
max_tokens: int
|
||||
max_tokens: Optional[int] = None
|
||||
messages: list[AnthropicMessage]
|
||||
system: Optional[Union[str, list]] = None
|
||||
tools: Optional[list[AnthropicTool]] = None
|
||||
|
|
@ -632,6 +632,10 @@ class AnthropicMessagesRequest(BaseModel):
|
|||
top_k: Optional[int] = None
|
||||
stop_sequences: Optional[list[str]] = None
|
||||
metadata: Optional[dict] = None
|
||||
# [x-unsloth] extensions — mirror the OpenAI endpoint convenience fields
|
||||
enable_tools: Optional[bool] = None
|
||||
enabled_tools: Optional[list[str]] = None
|
||||
session_id: Optional[str] = None
|
||||
model_config = {"extra": "allow"}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -2255,16 +2255,26 @@ async def anthropic_messages(
|
|||
cancel_event = threading.Event()
|
||||
|
||||
# ── Tool-calling path ─────────────────────────────────────
|
||||
use_tools = (
|
||||
payload.tools
|
||||
and len(payload.tools) > 0
|
||||
and llama_backend.supports_tools
|
||||
# Two ways to enable tools:
|
||||
# 1. Anthropic-style: send full tool definitions in payload.tools
|
||||
# 2. Unsloth shorthand: enable_tools=true + optional enabled_tools list
|
||||
use_tools = llama_backend.supports_tools and (
|
||||
(payload.tools and len(payload.tools) > 0)
|
||||
or payload.enable_tools
|
||||
)
|
||||
|
||||
if use_tools:
|
||||
from core.inference.tools import ALL_TOOLS
|
||||
|
||||
openai_tools = anthropic_tools_to_openai(payload.tools)
|
||||
if payload.tools and len(payload.tools) > 0:
|
||||
openai_tools = anthropic_tools_to_openai(payload.tools)
|
||||
elif payload.enabled_tools is not None:
|
||||
openai_tools = [
|
||||
t for t in ALL_TOOLS
|
||||
if t["function"]["name"] in payload.enabled_tools
|
||||
]
|
||||
else:
|
||||
openai_tools = ALL_TOOLS
|
||||
|
||||
# Build tool-use system prompt nudge (same logic as /chat/completions)
|
||||
_tool_names = {t["function"]["name"] for t in openai_tools}
|
||||
|
|
@ -2339,6 +2349,7 @@ async def anthropic_messages(
|
|||
max_tool_iterations = 25,
|
||||
auto_heal_tool_calls = True,
|
||||
tool_call_timeout = 300,
|
||||
session_id = payload.session_id,
|
||||
)
|
||||
|
||||
if payload.stream:
|
||||
|
|
|
|||
|
|
@ -41,13 +41,19 @@ from core.inference.anthropic_compat import (
|
|||
class TestAnthropicModels:
|
||||
|
||||
def test_minimal_request(self):
|
||||
req = AnthropicMessagesRequest(
|
||||
messages = [{"role": "user", "content": "Hi"}],
|
||||
)
|
||||
assert req.max_tokens is None
|
||||
assert req.model == "default"
|
||||
assert req.stream is False
|
||||
|
||||
def test_max_tokens_optional(self):
|
||||
req = AnthropicMessagesRequest(
|
||||
max_tokens = 100,
|
||||
messages = [{"role": "user", "content": "Hi"}],
|
||||
)
|
||||
assert req.max_tokens == 100
|
||||
assert req.model == "default"
|
||||
assert req.stream is False
|
||||
|
||||
def test_system_as_string(self):
|
||||
req = AnthropicMessagesRequest(
|
||||
|
|
@ -81,6 +87,25 @@ class TestAnthropicModels:
|
|||
)
|
||||
assert req.stream is False
|
||||
|
||||
def test_enable_tools_shorthand(self):
|
||||
req = AnthropicMessagesRequest(
|
||||
messages = [{"role": "user", "content": "Hi"}],
|
||||
enable_tools = True,
|
||||
enabled_tools = ["web_search", "python"],
|
||||
session_id = "my-session",
|
||||
)
|
||||
assert req.enable_tools is True
|
||||
assert req.enabled_tools == ["web_search", "python"]
|
||||
assert req.session_id == "my-session"
|
||||
|
||||
def test_extension_fields_default_none(self):
|
||||
req = AnthropicMessagesRequest(
|
||||
messages = [{"role": "user", "content": "Hi"}],
|
||||
)
|
||||
assert req.enable_tools is None
|
||||
assert req.enabled_tools is None
|
||||
assert req.session_id is None
|
||||
|
||||
def test_response_model_defaults(self):
|
||||
resp = AnthropicMessagesResponse()
|
||||
assert resp.type == "message"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue