{"record":{"id":"8de3a4d61bd5c540","repo":"TauricResearch/TradingAgents","slug":"self-model-name-has-no-structured-output-method","errorCode":null,"errorMessage":"{self.model_name} has no structured-output method available; agent factories will fall back to free-text generation.","messagePattern":"(.+?) has no structured-output method available; agent factories will fall back to free-text generation\\.","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"warning","filePath":"tradingagents/llm_clients/openai_client.py","lineNumber":41,"sourceCode":"    ``with_structured_output`` consults the per-model capability table\n    (``capabilities.get_capabilities``) to pick the method and to decide\n    whether ``tool_choice`` may be sent. Models that reject ``tool_choice``\n    (e.g. DeepSeek V4 and reasoner — per their official tool-calling\n    guide) still bind the schema as a tool, but no ``tool_choice``\n    parameter is sent.\n\n    Provider-specific quirks beyond structured-output (e.g. DeepSeek's\n    reasoning_content roundtrip) live in subclasses so this base class\n    stays small.\n    \"\"\"\n\n    def invoke(self, input, config=None, **kwargs):\n        return normalize_content(super().invoke(input, config, **kwargs))\n\n    def with_structured_output(self, schema, *, method=None, **kwargs):\n        caps = get_capabilities(self.model_name)\n        if caps.preferred_structured_method == \"none\":\n            raise NotImplementedError(\n                f\"{self.model_name} has no structured-output method available; \"\n                f\"agent factories will fall back to free-text generation.\"\n            )\n        method = method or caps.preferred_structured_method\n        # When the model rejects tool_choice, suppress langchain's hardcoded\n        # value. The schema is still bound as a tool — exactly what\n        # DeepSeek's official tool-calling examples do.\n        if method == \"function_calling\" and not caps.supports_tool_choice:\n            kwargs.setdefault(\"tool_choice\", None)\n        return super().with_structured_output(schema, method=method, **kwargs)\n\n\nclass LocalCompatibleChatOpenAI(NormalizedChatOpenAI):\n    \"\"\"OpenAI-compatible client for arbitrary local servers (LM Studio, vLLM,\n    llama.cpp via the generic ``openai_compatible`` provider).\n\n    Their tool-calling support varies, and many reject the object-form\n    ``tool_choice`` langchain sends for function-calling structured output. Bind","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/TauricResearch/TradingAgents/blob/a33fd4c0f134485a43553a2c23a63cb14adbd88f/tradingagents/llm_clients/openai_client.py#L23-L59","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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."],"exampleFix":"# before\nstructured = client.with_structured_output(schema)  # NotImplementedError\n\n# after\ntry:\n    structured = client.with_structured_output(schema)\nexcept NotImplementedError:\n    structured = client  # agent factories already do this fallback; use free-text + parse","handlingStrategy":"fallback","validationCode":"from tradingagents.llm_clients.model_capabilities import get_capabilities\n\ndef supports_structured_output(model_name: str) -> bool:\n    return get_capabilities(model_name).preferred_structured_method != 'none'","typeGuard":null,"tryCatchPattern":"try:\n    structured_client = client.with_structured_output(schema)\nexcept NotImplementedError:\n    # same fallback the agent factories use: free-text generation + own parsing\n    structured_client = client","preventionTips":["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."],"tags":["llm","structured-output","capabilities","fallback"],"backgroundTag":null,"analyzedSha":"a33fd4c0f134485a43553a2c23a63cb14adbd88f","analyzedAt":"2026-08-14T19:45:16.920Z","schemaVersion":2},"datasetVersion":"2026-08-15T17:31:12.345Z"}