fix(langgraph): an enum output is not free text - #38
Open
MAabdelmoumen wants to merge 1 commit into
Open
Conversation
A single string output is treated as the agent's own answer: no structured
generation is requested, and the output is filled from the final message so a
text agent still works on models without structured-output support.
An enum was caught by that rule, because an enum *is* a string. The consequences
were invisible: no `AgentOutputModel` tool was ever bound, the model replied in
prose, and the free-text fallback stored that whole sentence as the value — so
the declared options were never enforced. An agent with one enum output returned
sentences instead of one of its own values, and a `BranchingNode` keyed on it
matched none of its paths (raising `KeyError: 'default'` when no otherwise edge
exists, or silently taking the fallback when one does).
An enum's schema names the only values the output may take, so free text can
never satisfy it: it now takes the structured path, where the tool call is forced
and the value is validated against the allowed set. A plain string output keeps
the free-text shortcut unchanged.
Verified: the new test fails without the change, and a live flow whose classifier
declares one enum output now returns `{"sentiment": "positive"}` where it
previously returned prose.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A single string output is treated as the agent's own free text: no structured generation is requested, and the output is filled from the final message. That keeps a plain text agent working on models without structured-output support.
An enum was caught by that rule, because an enum is a string. Nothing about the failure was visible:
AgentOutputModeltool was ever bound, so nothing forced the model to answer structurally;So the declared options were never enforced. An agent with one enum output
sentiment: positive | negative | neutralanswered:and a
BranchingNodekeyed on that value matched none of its paths — raisingKeyError: 'default'when nootherwiseedge exists, or silently taking the fallback when one does.Fix
An enum's schema names the only values the output may take, so free text can never satisfy it. It now takes the structured path, where the tool call is forced and the value is validated against the allowed set.
A plain string output keeps the free-text shortcut, unchanged.
Verification
assert True is False) and passes with itflows/test_agentnode.py,flows/test_managerworkers_node.py,flows/test_swarm_node.py,flows/test_branchingnode.py— no change in failure counts (the remaining failures need live LLM endpoints){"sentiment": "positive"}where it previously returned proseNote
Only the enum case changes here. A plain single string field declared through a JSON output format still returns prose — whether that should honour the schema is a product decision, not a defect, so it is left alone.