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. BindView on GitHub (pinned to a33fd4c0f1)
Solutions
- Switch to a model that supports structured output (function calling or JSON mode), e.g. a current GPT/DeepSeek model.
- 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.
- 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
- Check model capabilities before selecting a model for structured-output-heavy agents.
- Prefer models with function calling or JSON mode when schemas matter.
- Implement a JSON-extraction fallback parser for free-text mode.
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.