Skip to content

Allow setting tool_choice #2799

@moritzwilksch

Description

@moritzwilksch

Description

This might also be a bug / unintended behavior?

Request: Force non-tool-call although tools are defined

I'd like to be able to create an OpenAI generation with tool_choice='none' such that - even though tools are defined - the model is forced to respond with a non-tool-call. This can be advantageous for cache hit rates as opposed to setting function_tools=[] for the generation in agentic loops.

Output mode?

My intuition would be I'd be able to set output_mode = "text" since there exists an output_mode = "text_or_tool" which implies that "text" means "text, not tool". However, this is not the case. Is this intentional or an inconsistency / bug?

Example

# %%
from dotenv import load_dotenv
from pydantic import BaseModel
from pydantic_ai.direct import model_request_sync
from pydantic_ai.messages import ModelRequest, SystemPromptPart, UserPromptPart
from pydantic_ai.models import ModelRequestParameters
from pydantic_ai.models.openai import OpenAIChatModel
from pydantic_ai.tools import ToolDefinition

load_dotenv()

model = OpenAIChatModel("gpt-4.1-mini")
request = ModelRequest(
    [
        SystemPromptPart(
            "Before answering any weather-related question use the `get_current_weather` tool."
        ),
        UserPromptPart("Hows the temp in Berlin?"),
    ]
)


class Params(BaseModel):
    location: str
    date: str


response = model_request_sync(
    messages=[request],
    model=model,
    model_request_parameters=ModelRequestParameters(
        output_mode="text",  # how do I emulate tool_choice='none'?
        function_tools=[
            ToolDefinition(
                name="get_current_weather",
                description="Get the current weather in a given location",
                parameters_json_schema=Params.model_json_schema(),
            )
        ],
    ),
)
print(response)
ModelResponse(
    parts=[
        ToolCallPart(
            tool_name="get_current_weather",
            args='{"location":"Berlin","date":"2024-06-05"}',
            tool_call_id="call_P9Ln6s7Np1LnlYxZlrH6HGvL",
        )
    ],
    usage=RequestUsage(
        input_tokens=73,
        output_tokens=24,
        details={
            "accepted_prediction_tokens": 0,
            "audio_tokens": 0,
            "reasoning_tokens": 0,
            "rejected_prediction_tokens": 0,
        },
    ),
    model_name="gpt-4.1-mini-2025-04-14",
    timestamp=datetime.datetime(2025, 9, 4, 9, 34, 1, tzinfo=TzInfo(UTC)),
    provider_name="openai",
    provider_response_id="chatcmpl-CC0dtBsakxMEVJGvnPnL6OVIGBrkq",
)

References

No response

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions