Skip to content

Conversation

@HavenDV
Copy link
Contributor

@HavenDV HavenDV commented Aug 26, 2025

Summary by CodeRabbit

  • New Features

    • Expanded tool selection in chat completions: tool_choice now accepts either a string or a tools object, supporting modes “none,” “auto,” “required,” and explicit tool specification.
  • Documentation

    • Clarified tool_choice behavior and usage, including new modes and how to provide explicit tool definitions.

@coderabbitai
Copy link

coderabbitai bot commented Aug 26, 2025

Walkthrough

The OpenAPI schema for OpenAIChatCompletionsIn.tool_choice was changed from a string to a polymorphic anyOf (string or ChatTools object) with an expanded description covering "none," "auto," "required," and explicit tool selection.

Changes

Cohort / File(s) Summary
OpenAPI schema: Chat Completions tool_choice
src/libs/DeepInfra/openapi.yaml
Updated tool_choice from type: string to anyOf: [string, #/components/schemas/ChatTools]; description expanded to document modes: "none," "auto," "required," and explicit defined-tool semantics.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Client
  participant API as Chat Completions API
  participant Router as Tool Router
  participant Tool as Tool Executor

  rect rgb(240,248,255)
  note right of Client: Submit chat request with tool_choice
  Client->>API: POST /chat/completions<br/>tool_choice
  end

  alt tool_choice is "none" or "auto"
    API->>Router: Determine tool call (if any)
    opt auto selects a tool
      Router->>Tool: Invoke selected tool
      Tool-->>Router: Result
    end
    Router-->>API: Tool decision/result
    API-->>Client: Chat completion (with/without tool call)
  else tool_choice is "required"
    API->>Router: Must choose a tool
    Router->>Tool: Invoke required tool
    Tool-->>Router: Result
    API-->>Client: Chat completion with tool call
  else tool_choice is ChatTools object (explicit)
    note over API,Router: Object may specify a defined tool to call
    API->>Router: Use provided ChatTools definition/selection
    Router->>Tool: Invoke specified tool
    Tool-->>Router: Result
    API-->>Client: Chat completion with explicit tool call
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I twitch my ears at schemas new,
A whisker-flick—now tools can choose!
String or kit, I hop on through,
AnyOf paths the API will use.
With tidy paws, I mark the lane,
“Required? Auto?”—carrots sustain.
Thump—explicit tools now reign! 🥕

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.

✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bot/update-openapi_202508262116

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@HavenDV HavenDV enabled auto-merge (squash) August 26, 2025 21:17
@HavenDV HavenDV merged commit 072971a into main Aug 26, 2025
3 of 4 checks passed
@HavenDV HavenDV deleted the bot/update-openapi_202508262116 branch August 26, 2025 21:18
@coderabbitai coderabbitai bot changed the title feat:@coderabbitai feat:OpenAPI: tool_choice now anyOf (string or ChatTools), docs expanded Aug 26, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (2)
src/libs/DeepInfra/openapi.yaml (2)

6401-6404: Clarify description and add examples for both forms

The current description mentions a “defined tool” but doesn’t show the object shape or the requirement that it must match tools[]. Please tighten language and add examples to reduce client ambiguity.

Apply this diff in-place:

-          description: Controls which (if any) function is called by the model. none means the model will not call a function and instead generates a message. auto means the model can pick between generating a message or calling a function. required means the model must call a function. defined tool means the model must call that specific tool. none is the default when no functions are present. auto is the default if functions are present.
+          description: Controls tool calling behavior.
+            - "none": model will not call a tool and will only generate a message.
+            - "auto": model may choose to generate a message or call a tool.
+            - "required": model must call a tool (one of tools[]).
+            - object form: {"type":"function","function":{"name":"<toolName>"}} forces that specific tool to be called. The name must match one of tools[].function.name.
+            Default behavior: if tools are provided and tool_choice is omitted, providers typically default to "auto"; if no tools are provided, tool calls are not possible.
+          examples:
+            - none
+            - auto
+            - required
+            - {"type":"function","function":{"name":"get_weather"}}

6400-6405: Consider an explicit default for better SDK typings

If you want codegen to surface a concrete default, set default: auto on the property (applies to the string branch). This matches common provider behavior and yields clearer client stubs.

Apply this small tweak:

         tool_choice:
           title: Tool Choice
+          default: auto

Note: with oneOf this default will validate against the string branch.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 4ff3e93 and 32bc393.

⛔ Files ignored due to path filters (5)
  • src/libs/DeepInfra/Generated/DeepInfra..JsonSerializerContext.g.cs is excluded by !**/generated/**
  • src/libs/DeepInfra/Generated/DeepInfra.DeepInfraClient.OpenaiChatCompletions.g.cs is excluded by !**/generated/**
  • src/libs/DeepInfra/Generated/DeepInfra.IDeepInfraClient.OpenaiChatCompletions.g.cs is excluded by !**/generated/**
  • src/libs/DeepInfra/Generated/DeepInfra.JsonSerializerContextTypes.g.cs is excluded by !**/generated/**
  • src/libs/DeepInfra/Generated/DeepInfra.Models.OpenAIChatCompletionsIn.g.cs is excluded by !**/generated/**
📒 Files selected for processing (1)
  • src/libs/DeepInfra/openapi.yaml (1 hunks)
🔇 Additional comments (2)
src/libs/DeepInfra/openapi.yaml (2)

6401-6404: Document cross-field constraint with tools[]

Schema can’t enforce “tool_choice.function.name ∈ tools[].function.name” in OAS 3.0. Add a note so server-side validation can return a 422 when the selector doesn’t match any tool.

Add this sentence at the end of the description: “If object form is used, the function name MUST match one defined in tools[].function.name; otherwise the request is invalid (422).”


6401-6404: Backward compatibility note

This is a breaking change for generated SDKs and server request deserializers that previously treated tool_choice as a string. Please flag it in release notes and bump the API version or changelog accordingly.

I can help generate client impact notes and a migration checklist if desired.

Comment on lines +6401 to +6404
anyOf:
- type: string
- $ref: '#/components/schemas/ChatTools'
description: Controls which (if any) function is called by the model. none means the model will not call a function and instead generates a message. auto means the model can pick between generating a message or calling a function. required means the model must call a function. defined tool means the model must call that specific tool. none is the default when no functions are present. auto is the default if functions are present.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

Avoid reusing ChatTools in tool_choice; introduce a selector object that only needs a function name

Using ChatTools here invites redefining a tool and duplicating/contradicting entries in tools[]. OpenAI-style selection only needs the function name. Define a minimal selector object and reference that from tool_choice.

Add these schemas under components/schemas (outside this hunk):

ToolChoiceFunction:
  title: ToolChoiceFunction
  required: [type, function]
  type: object
  properties:
    type:
      title: Type
      type: string
      enum: [function]
      default: function
    function:
      $ref: '#/components/schemas/ToolChoiceFunctionName'

ToolChoiceFunctionName:
  title: ToolChoiceFunctionName
  required: [name]
  type: object
  properties:
    name:
      title: Name
      type: string
      description: Name of the function to call. Must match one of tools[].function.name.

This keeps tools[] for full definitions (parameters, descriptions) and tool_choice for selection only.


🛠️ Refactor suggestion

Constrain tool_choice to valid values and prefer oneOf for disjoint types

Right now any string is accepted, which weakens validation and SDK typings. Since object vs. string are disjoint, oneOf is a better fit and the string branch should enumerate the only allowed literals.

Apply this diff within this block:

-          anyOf:
-            - type: string
-            - $ref: '#/components/schemas/ChatTools'
+          oneOf:
+            - type: string
+              enum: [none, auto, required]
+            - $ref: '#/components/schemas/ToolChoiceFunction'

And add the supporting schema below in components/schemas (example provided in a separate block in the next comment).

🤖 Prompt for AI Agents
In src/libs/DeepInfra/openapi.yaml around lines 6401-6404, replace the anyOf
block with a oneOf that distinguishes a literal enum string branch and an object
branch referencing ChatTools, and constrain the string branch to the allowed
literals (none, auto, required, <tool-name> not allowed here — only the
enumerated keywords). Then add a new components/schemas entry (e.g.,
ToolChoiceString) that defines the enum of allowed string values and update the
oneOf to reference that schema alongside the existing ChatTools ref; ensure the
description is preserved and the oneOf usage reflects disjoint types for correct
validation and SDK typing.

💡 Verification agent

❓ Verification inconclusive

Validate the updated spec and sample payloads

Run a quick spec validation and probe example payloads for the new oneOf branch to avoid regressions.


🏁 Script executed:

#!/bin/bash
set -euo pipefail

# 1) Validate OpenAPI (Python validator)
pip -q install openapi-spec-validator==0.7.1 prance==23.6.21 >/dev/null

python - <<'PY'
from openapi_spec_validator import validate_spec
from prance import ResolvingParser
import sys, json

spec_path = "src/libs/DeepInfra/openapi.yaml"
parser = ResolvingParser(spec_path, resolve_types=ResolvingParser.RESOLVE_INTERNAL)
validate_spec(parser.specification)
print("OpenAPI spec validated OK")

# Sanity-check the tool_choice schema shape
oc = parser.specification["components"]["schemas"]["OpenAIChatCompletionsIn"]["properties"]["tool_choice"]
print("tool_choice schema keys:", list(oc.keys()))
PY

# 2) Optional: spot-check common generators parse it (no generation, just presence)
rg -nC2 'tool_choice' src/libs/DeepInfra/openapi.yaml || true

Length of output: 686


Validate the updated OpenAPI spec with a YAML-based loader

I’ve adjusted the validation approach to avoid the ResolvingParser API mismatch and directly load the YAML. Please run the following to confirm there are no schema errors and that the new anyOf branch for tool_choice is correctly recognized:

– Verify that the anyOf array includes both the string type and the ChatTools $ref.
– Spot-check any code generators or clients (e.g., your OpenAPI-driven SDKs) to ensure they parse the updated tool_choice property without errors.
– Manually craft and send a sample payload covering each anyOf option (plain string, ChatTools object) to your service endpoint to confirm runtime handling.


🏁 Script executed:

#!/usr/bin/env bash
set -euo pipefail

# Install validator and YAML parser
pip install -q openapi-spec-validator==0.7.1 pyyaml==6.0 >/dev/null

# Validate the full spec and inspect the tool_choice schema
python3 - <<'PY'
import yaml
from openapi_spec_validator import validate_spec

spec_path = "src/libs/DeepInfra/openapi.yaml"
with open(spec_path, "r") as f:
    spec = yaml.safe_load(f)

# 1) Validate the overall OpenAPI document
validate_spec(spec)
print("✅ OpenAPI spec validated OK")

# 2) Sanity-check the new anyOf branch on tool_choice
tool_choice = spec["components"]["schemas"]["OpenAIChatCompletionsIn"]["properties"]["tool_choice"]
print("tool_choice schema keys:", list(tool_choice.keys()))
print("tool_choice anyOf entries:", tool_choice.get("anyOf"))
PY

Length of output: 1101


Critical: Fix invalid parameter schema in OpenAPI spec

The OpenAPI validation failed due to an invalid cookie parameter definition for session in the /payment/checklist GET operation. The schema uses type: 'String' (capital “S”), which isn’t a valid OpenAPI primitive. It must be lowercase string. Please correct this and re-validate.

• Location to fix (in src/libs/DeepInfra/openapi.yaml):

paths:
  /payment/checklist:
    get:
      parameters:
        - name: session
          in: cookie
          schema:
            type: string    # lowercase “string” instead of “String”

After updating, rerun the validation:

pip install -q openapi-spec-validator pyyaml
python3 - <<'PY'
import yaml
from openapi_spec_validator import validate_spec

spec = yaml.safe_load(open("src/libs/DeepInfra/openapi.yaml"))
validate_spec(spec)
print("✅ OpenAPI spec validated OK")
PY

Once that’s green, you can then proceed to spot-check the new tool_choice anyOf branch and sample payloads.

🤖 Prompt for AI Agents
In src/libs/DeepInfra/openapi.yaml around lines 6401-6404 (and specifically in
the /payment/checklist GET parameters), the cookie parameter "session" uses an
invalid OpenAPI primitive type "String" (capital S); change it to lowercase
"string" in the parameter's schema, save the file, then re-run the OpenAPI
validator (install openapi-spec-validator and pyyaml if needed) and run the
provided python validation snippet to ensure the spec is valid; after
validation, spot-check the new tool_choice anyOf branch and sample payloads for
any remaining schema issues.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants