Skip to content

fix(langgraph): add description to OCI structured-output schema - #234

Closed
AmirF194 wants to merge 2 commits into
oracle:mainfrom
AmirF194:fix/232-oci-cohere-structured-output-description
Closed

fix(langgraph): add description to OCI structured-output schema#234
AmirF194 wants to merge 2 commits into
oracle:mainfrom
AmirF194:fix/232-oci-cohere-structured-output-description

Conversation

@AmirF194

Copy link
Copy Markdown

Root cause

LlmNodeExecutor.__init__ (_node_execution.py) builds the LangGraph structured-output
schema for an LlmNode as a bare dict with only title, type and properties, then
passes it to self.llm.with_structured_output(json_schema).

For an OciGenAiConfig-backed model, that call reaches langchain_oci's
ChatOCIGenAI.bind_tools -> convert_to_oci_tool. The generic provider (Meta/OpenAI/Gemini
model ids) only requires title and properties, so it happens to accept this dict. The
Cohere provider (cohere.* model ids) additionally requires description:

if not all(k in tool for k in ("title", "description", "properties")):
    raise ValueError("Unsupported dict type. Tool must be a BaseTool instance, "
                      "JSON schema dict, or Pydantic model.")

so any Cohere-family model configured with a structured (non-single-string) LlmNode
output fails at executor construction time, before any request reaches OCI, matching the
report on #232.

Fix

Add a static description key to the schema dict, mirroring the existing title comment.

Verification

  • Reproduced against current HEAD in a clean python:3.12-slim container (pyagentspec
    installed editable from this checkout, provenance checked via module.__file__):
    constructing LlmNodeExecutor for an OciGenAiConfig(model_id="cohere.command-a-...")
    node with two non-string outputs raises the ValueError above; a Meta/generic model id
    does not, which is why this is provider-specific rather than universal.
  • Added test_llmnodeexecutor_structured_output_supported_across_providers
    (test_ocigenai_conversion.py), parametrized over a Cohere and a Meta model id, using a
    throwaway locally-generated OCI API key so it needs no real account or network call. It
    fails on main for the Cohere case and passes on this branch for both, run both ways in
    the same container.
  • black, isort, flake8 --select C801 (including the copyright check) and bandit -c bandit.yaml -r pyagentspec/ all clean on the two changed files. mypy is not run here:
    the CI job excludes pyagentspec/src/pyagentspec/adapters.
  • Full pytest tests (both changed and unchanged) with SKIP_LLM_TESTS=1, matching this
    repo's CI env: same 10 failed / 1042 passed / 666 skipped / 26 errors before and after this
    diff, all pre-existing and traced to optional extras not installed in this container
    (langchain_ollama, langgraph_swarm), not to this change.
  • Not verified: like every other test in this file that constructs an OciGenAiConfig
    (including the pre-existing test_reverse_convert_chatocigenai_to_agentspec), the new test
    is skipped under the project's standard SKIP_LLM_TESTS=1 CI run; I could only exercise it
    locally with that flag unset.

Fixes #232

LlmNodeExecutor built the LangGraph structured-output JSON schema with
only "title", "type" and "properties". langchain_oci's CohereProvider
requires "description" to also be present and raises ValueError for any
dict missing it, so every Cohere-family OciGenAiConfig model with a
non-string LlmNode output failed at construction time. The generic
provider (Meta/OpenAI/Gemini) only needs "title" and "properties", so it
was unaffected, which is why this depends on model_id / provider choice.

Fixes oracle#232

Signed-off-by: Amir Fathi <amirfathi.me@gmail.com>
@AmirF194
AmirF194 requested a review from a team August 21, 2026 08:25
@oracle-contributor-agreement

Copy link
Copy Markdown

Thank you for your pull request and welcome to our community! To contribute, please sign the Oracle Contributor Agreement (OCA).
The following contributors of this PR have not signed the OCA:

To sign the OCA, please create an Oracle account and sign the OCA in Oracle's Contributor Agreement Application.

When signing the OCA, please provide your GitHub username. After signing the OCA and getting an OCA approval from Oracle, this PR will be automatically updated.

If you are an Oracle employee, please make sure that you are a member of the main Oracle GitHub organization, and your membership in this organization is public.

@oracle-contributor-agreement oracle-contributor-agreement Bot added the OCA Required At least one contributor does not have an approved Oracle Contributor Agreement. label Aug 21, 2026
@cesarebernardis
cesarebernardis self-requested a review August 24, 2026 09:28
Comment thread pyagentspec/tests/adapters/langgraph/llms/test_ocigenai_conversion.py Outdated
… unit test

Per review: the previous test built a real ChatOCIGenAI per provider via
AgentSpecToLangGraphConverter, which needs a throwaway OCI API-key config
and does not directly assert on the schema LlmNodeExecutor builds. Replace
it with a unit test that monkeypatches _node_execution.BaseChatModel with a
fake that captures the with_structured_output schema, and asserts its
description and properties directly, near LlmNodeExecutor.

Signed-off-by: Amir Fathi <amirfathi.me@gmail.com>
@AmirF194

Copy link
Copy Markdown
Author

Pushed 3694bb6: replaced the parametrized OCI test with a unit test near LlmNodeExecutor that monkeypatches _node_execution.BaseChatModel with a fake capturing the with_structured_output schema, and asserts its description and properties directly. No OCI config needed anymore.

@cesarebernardis

Copy link
Copy Markdown
Member

Pushed 3694bb6: replaced the parametrized OCI test with a unit test near LlmNodeExecutor that monkeypatches _node_execution.BaseChatModel with a fake capturing the with_structured_output schema, and asserts its description and properties directly. No OCI config needed anymore.

LGTM.

To proceed with the next steps to merge this PR, I would need you to sign the Oracle Contributor Agreement (OCA). Please check the comment at #234 (comment)

@AmirF194

Copy link
Copy Markdown
Author

Closing this one. I've decided not to sign the Oracle Contributor Agreement, so it can't go any further, and it isn't fair to leave it sitting in your queue.

Thanks for the review time, the fix itself is small if anyone wants to pick it up: the OCI structured-output schema needs a description field or the LangGraph path drops it.

@AmirF194 AmirF194 closed this Aug 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

OCA Required At least one contributor does not have an approved Oracle Contributor Agreement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

LangGraph adapter fails to load OciGenAiConfig LlmNode with structured output

2 participants