Skip to content

Native tool calling not working (ctx.tools is always None) #1

Description

@cizekmilan

Description

When using mcs-driver-rest with models that support native tool/function calling, ctx.tools is always None. Instead, the driver falls back to embedding tools into system_message as text.

This happens even for models that clearly support tool calling.


Tested models

  • gpt-4
  • gpt-4.5
  • gpt-5
  • gpt-5.2
  • local model (gpt-oss-120b via vLLM with --tool-call-parser openai)

Tested OpenAPI sources

  • Custom FastAPI app (/openapi.json)
  • Petstore example (https://petstore3.swagger.io/api/v3/openapi.json)
  • Context7 (https://mcsd.io/context7.json)

Expected behavior

When passing a model that supports tool calling:

ctx = driver.get_driver_context(model_name=LLM_MODEL)

ctx.tools should contain tool definitions in OpenAI format so they can be passed to:

client.chat.completions.create(..., tools=ctx.tools)

Actual behavior

ctx.tools is always:

None

Tools are instead embedded into ctx.system_message as text instructions.

As a result:

  • Native tool calling cannot be used
  • The system falls back to JSON-in-text parsing

Minimal reproducible example

from openai import OpenAI
from mcs.driver.rest import RestDriver

LLM_API_KEY = "..."
LLM_MODEL = "gpt-5.2"

client = OpenAI(api_key=LLM_API_KEY)

driver = RestDriver(
    url="http://127.0.0.1:8000/openapi.json"
)

ctx = driver.get_driver_context(model_name=LLM_MODEL)

print("TOOLS:", ctx.tools)  # always None

messages = [
    {"role": "system", "content": "You are a helpful assistant. Use tools when appropriate."},
    #{"role": "system", "content": ctx.system_message},
    {"role": "user", "content": "Find customer Kralova and show tickets and payments."},
]

completion = client.chat.completions.create(
    model=LLM_MODEL,
    messages=messages,
    tools=ctx.tools,
)

print(completion.choices[0].message)

Notes

  • The OpenAPI schema is valid and tools are correctly present in system_message
  • The issue appears to be in model capability detection inside the driver
  • It seems to rely on a hardcoded allowlist or model name matching
  • Newer models (e.g. gpt-5.x) are not recognized as supporting tools

Suggested fix

  • Do not rely on static model name detection

  • Either:

    • always return tools when OpenAPI is valid
    • or allow forcing native tool mode (e.g. force_tools=True)
    • or detect capability dynamically

Impact

This prevents using native tool calling with modern models and forces fallback behavior, even when unnecessary.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions