test: stabilize profile workflow e2e fixtures - #366
Conversation
📝 WalkthroughWalkthroughThe structured-output parser now recognizes optional or union-wrapped list fields when wrapping top-level JSON arrays. Unit tests cover optional, bare, and multi-field schemas. E2e fixtures share customer-support extraction settings and skip the run check. ChangesStructured output parsing
Customer-support e2e fixtures
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
reflexio/server/llm/_litellm_structured_output.py (1)
56-64: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueRestrict recursive list detection to
UnionandAnnotatedtypes.The current implementation recurses into the generic arguments of any type, including
dict,tuple, andCallable. While Pydantic's downstream validation mitigates practical risks by failing on invalid types anyway, the logic conceptually violates its intent ("Return whether an annotation accepts a list value") by returningTruefor types likedict[str, list[int]].Consider restricting the recursion to
Union(which handlesOptionaland Python 3.10|unions) andAnnotatedtypes to ensure the list detection remains precise.💡 Proposed refactor to restrict recursion
def _is_list_annotation(annotation: Any) -> bool: """Return whether an annotation accepts a list value.""" if annotation is list or get_origin(annotation) is list: return True + + import typing + origin = get_origin(annotation) + is_union = origin is typing.Union or getattr(origin, "__name__", "") == "UnionType" + is_annotated = origin is getattr(typing, "Annotated", type(None)) + if not (is_union or is_annotated): + return False + return any( _is_list_annotation(arg) for arg in get_args(annotation) if arg is not type(None) )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@reflexio/server/llm/_litellm_structured_output.py` around lines 56 - 64, Update _is_list_annotation so recursive traversal occurs only for Union types, including Optional and Python 3.10 union syntax, and Annotated types; do not recurse through arbitrary generic arguments such as dict, tuple, or Callable. Preserve direct list detection while ensuring nested list types inside unrelated containers return False.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@reflexio/server/llm/_litellm_structured_output.py`:
- Around line 56-64: Update _is_list_annotation so recursive traversal occurs
only for Union types, including Optional and Python 3.10 union syntax, and
Annotated types; do not recurse through arbitrary generic arguments such as
dict, tuple, or Callable. Preserve direct list detection while ensuring nested
list types inside unrelated containers return False.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro Plus
Run ID: c2b87068-a678-4028-83f1-675e3ce48afb
📒 Files selected for processing (3)
reflexio/server/llm/_litellm_structured_output.pytests/e2e_tests/conftest.pytests/server/llm/test_litellm_client_unit.py
Summary
Changes
list[...] | Nonewrapper schemas.Test Plan
uv run --no-sync ruff check open_source/reflexio/reflexio/server/llm/_litellm_structured_output.py open_source/reflexio/tests/e2e_tests/conftest.py open_source/reflexio/tests/server/llm/test_litellm_client_unit.pyuv run --no-sync pyright open_source/reflexio/reflexio/server/llm/_litellm_structured_output.py open_source/reflexio/tests/e2e_tests/conftest.py open_source/reflexio/tests/server/llm/test_litellm_client_unit.pyuv run --no-sync pytest open_source/reflexio/tests/server/llm/test_litellm_client_unit.py -q -o addopts=uv run --no-sync pytest open_source/reflexio/tests/e2e_tests/test_profile_workflows.py -m e2e -o addopts=uv run --no-sync pytest open_source/reflexio/tests/e2e_tests/test_interaction_workflows.py -m e2e -o addopts=Summary by CodeRabbit
Bug Fixes
Tests