Skip to content

feat: Add tool_choice parameter for forced tool calling #217

@Kamilbenkirane

Description

@Kamilbenkirane

Problem

celeste exposes tools= to define available tools, but has no way to control whether the model must use them. Every comparable SDK supports this as a standard parameter:

  • openai-python: tool_choice on chat.completions.create()
  • anthropic-python: tool_choice on messages.create()
  • google-genai: tool_config on generate_content()
  • mistralai: tool_choice on chat.complete()

Proposed Unified API

response = await celeste.text.generate(
    prompt="...",
    tools=[my_tool],
    tool_choice="required",  # NEW parameter
)

Unified values

Celeste value Behavior
"auto" Model decides (default)
"required" MUST call at least one tool
"none" Cannot call any tool
{"name": "X"} MUST call specific tool X

Provider mapping

Celeste OpenAI Anthropic Gemini Mistral
"auto" "auto" {"type": "auto"} mode: "AUTO" "auto"
"required" "required" {"type": "any"} mode: "ANY" "any"
"none" "none" {"type": "none"} mode: "NONE" "none"
{"name": "X"} {"type": "function", "function": {"name": "X"}} {"type": "tool", "name": "X"} mode: "ANY", allowedFunctionNames: ["X"] {"type": "function", "function": {"name": "X"}}

Implementation

Fits naturally into the existing parameter mapper architecture:

  1. Add TOOL_CHOICE = "tool_choice" to TextParameter enum
  2. Add tool_choice field to TextParameters
  3. Create provider-specific ToolChoiceMapper for each provider (same pattern as ToolsMapper, ThinkingMapper)

References

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions