TauricResearch/TradingAgents · warning · NotImplementedError

{self.model_name} has no structured-output method available;

Error message

{self.model_name} has no structured-output method available; agent factories will fall back to free-text generation.

What it means

NotImplementedError raised by OpenAIClient.with_structured_output (tradingagents/llm_clients/openai_client.py) when the capability registry reports preferred_structured_method == 'none' for the model — i.e. the model supports neither JSON mode nor function calling. The message is informational: agent factories catch it and fall back to free-text generation with their own parsing.

Source

Thrown at tradingagents/llm_clients/openai_client.py:41

    ``with_structured_output`` consults the per-model capability table
    (``capabilities.get_capabilities``) to pick the method and to decide
    whether ``tool_choice`` may be sent. Models that reject ``tool_choice``
    (e.g. DeepSeek V4 and reasoner — per their official tool-calling
    guide) still bind the schema as a tool, but no ``tool_choice``
    parameter is sent.

    Provider-specific quirks beyond structured-output (e.g. DeepSeek's
    reasoning_content roundtrip) live in subclasses so this base class
    stays small.
    """

    def invoke(self, input, config=None, **kwargs):
        return normalize_content(super().invoke(input, config, **kwargs))

    def with_structured_output(self, schema, *, method=None, **kwargs):
        caps = get_capabilities(self.model_name)
        if caps.preferred_structured_method == "none":
            raise NotImplementedError(
                f"{self.model_name} has no structured-output method available; "
                f"agent factories will fall back to free-text generation."
            )
        method = method or caps.preferred_structured_method
        # When the model rejects tool_choice, suppress langchain's hardcoded
        # value. The schema is still bound as a tool — exactly what
        # DeepSeek's official tool-calling examples do.
        if method == "function_calling" and not caps.supports_tool_choice:
            kwargs.setdefault("tool_choice", None)
        return super().with_structured_output(schema, method=method, **kwargs)


class LocalCompatibleChatOpenAI(NormalizedChatOpenAI):
    """OpenAI-compatible client for arbitrary local servers (LM Studio, vLLM,
    llama.cpp via the generic ``openai_compatible`` provider).

    Their tool-calling support varies, and many reject the object-form
    ``tool_choice`` langchain sends for function-calling structured output. Bind

View on GitHub (pinned to a33fd4c0f1)

Solutions

  1. Switch to a model that supports structured output (function calling or JSON mode), e.g. a current GPT/DeepSeek model.
  2. Let the built-in fallback do its job: agent factories catch NotImplementedError and use free-text generation — no code change needed if output quality is acceptable.
  3. If you call with_structured_output directly, wrap it in try/except NotImplementedError and provide your own prompt-based JSON extraction.

Example fix

# before
structured = client.with_structured_output(schema)  # NotImplementedError

# after
try:
    structured = client.with_structured_output(schema)
except NotImplementedError:
    structured = client  # agent factories already do this fallback; use free-text + parse
Defensive patterns

Strategy: fallback

Validate before calling

from tradingagents.llm_clients.model_capabilities import get_capabilities

def supports_structured_output(model_name: str) -> bool:
    return get_capabilities(model_name).preferred_structured_method != 'none'

Try / catch

try:
    structured_client = client.with_structured_output(schema)
except NotImplementedError:
    # same fallback the agent factories use: free-text generation + own parsing
    structured_client = client

Prevention

When it happens

Trigger: Selecting a model whose capabilities entry has no structured-output method (some reasoning/local models), then letting an agent call with_structured_output(schema). get_capabilities(model_name) returns caps with preferred_structured_method='none' and the raise fires.

Common situations: Swapping in a local/Ollama or older model that lacks tool calling and JSON mode; using a model name not present in the capability registry defaults; upgrading the library so a model's capability entry changed.


AI-assisted analysis of TauricResearch/TradingAgents@a33fd4c0f1 (2026-08-14). Data as JSON: /api/errors/8de3a4d61bd5c540. Report an issue: GitHub.