feat: narrow MessageDict.role to RoleLiteral#89
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
✅ Files skipped from review due to trivial changes (1)
🚧 Files skipped from review as they are similar to previous changes (7)
📝 WalkthroughWalkthroughIntroduces ChangesRoleLiteral contract, parser coercion, validation, and tests
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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.
Inline comments:
In `@utils/jsonl_parser.py`:
- Around line 44-45: The `_HANDLED_ENTRY_TYPES` frozenset is missing
"file-history-snapshot" even though line 144 treats it as a known metadata
record type. Because it's absent from `_HANDLED_ENTRY_TYPES`, the entry type
falls through to the `_fallback_message()` call at lines 172-175, causing
spurious unknown message role warnings and synthetic system messages. Add
"file-history-snapshot" to the `_HANDLED_ENTRY_TYPES` frozenset so that this
entry type is recognized as a handled type and properly excluded from fallback
message processing.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 1002b380-cb9c-4365-85ab-3c67ada2e761
📒 Files selected for processing (6)
models/__init__.pymodels/search.pymodels/session.pytests/test_jsonl_parser.pytests/test_parser_fuzz.pyutils/jsonl_parser.py
|
@CodeRabbit , can you pleasee review this in more depth? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
echo "=== models/session.py ==="
cat models/session.py
echo ""
echo "=== models/search.py ==="
cat models/search.py
echo ""
echo "=== models/__init__.py ==="
cat models/__init__.py
echo ""
echo "=== utils/jsonl_parser.py ==="
cat utils/jsonl_parser.py
echo ""
echo "=== utils/validation.py ==="
cat utils/validation.py
echo ""
echo "=== tests/test_jsonl_parser.py ==="
cat tests/test_jsonl_parser.py
echo ""
echo "=== tests/test_parser_fuzz.py ==="
cat tests/test_parser_fuzz.py
echo ""
echo "=== tests/test_jsonl_validation.py ==="
cat tests/test_jsonl_validation.py
echo ""
echo "=== models/tool_results.py (reference pattern) ==="
cat models/tool_results.py 2>/dev/null || echo "File not found"Length of output: 77525
In-Depth Review:
|
| Area | Observation |
|---|---|
RoleLiteral definition |
Mirrors the established ToolNameLiteral pattern exactly. Clean. |
_VALID_ROLES from get_args |
Deriving the set at import time from the type alias means the set is always in sync with RoleLiteral — no manual duplication. |
validate_session_dict enhancement |
Adding role membership validation closes the runtime safety gap. Correct path format (messages[0].role), correct error detail. |
_SKIP_ENTRY_TYPES |
Explicit allowlist of types to silently skip is much cleaner than implicit ignore. |
Test for result role |
test_valid_unhandled_result_type_emits_result_role correctly exercises that a known-valid-but-unhandled type is emitted with the right role (not coerced to "system"). |
| Fuzz test update | test_unknown_record_type_is_graceful correctly updated to assert 2 messages instead of 1. |
models/__init__.py export |
RoleLiteral is properly added to __all__. |
Summary of actionable items
| Priority | Item | File |
|---|---|---|
| 🔴 | Remove always-true not in _HANDLED_ENTRY_TYPES guard |
utils/jsonl_parser.py |
| 🟡 | Use logging.getLogger(__name__) in _coerce_role |
utils/jsonl_parser.py |
| 🟡 | Store derived text in both "text" and "content" in _fallback_message |
utils/jsonl_parser.py |
| 🟡 | Use _extract_text(_normalize_content(...)) for list content |
utils/jsonl_parser.py |
| 🟢 | Add direct unit tests for _coerce_role |
tests/test_jsonl_parser.py |
|
@CodeRabbit , my last commit addressed seecond comment of @timon0305 ? |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
# Get all review comments on PR `#89`
gh pr view 89 --repo cppalliance/claude-code-chat-browser --comments --json comments,reviews 2>/dev/null | jq -r '
.comments[] | select(.author.login == "timon0305") |
"=== Comment by timon0305 (id: \(.id)) ===\n\(.body)\n"
' 2>/dev/null || true
echo "--- Review comments ---"
gh api repos/cppalliance/claude-code-chat-browser/pulls/89/comments 2>/dev/null | jq -r '
.[] | select(.user.login == "timon0305") |
"=== Review comment (id: \(.id)) at \(.path):\(.line) ===\n\(.body)\n"
' 2>/dev/null || true
echo "--- All issue/PR comments ---"
gh api repos/cppalliance/claude-code-chat-browser/issues/89/comments 2>/dev/null | jq -r '
.[] | select(.user.login == "timon0305") |
"=== Comment (id: \(.id)) ===\n\(.body)\n"
' 2>/dev/null || trueLength of output: 2020 🏁 Script executed: #!/bin/bash
# Get the latest commit on the PR branch and its diff
gh pr view 89 --repo cppalliance/claude-code-chat-browser --json headRefName,commits | jq -r '
"Branch: \(.headRefName)\nLatest commit: \(.commits[-1].oid) - \(.commits[-1].messageHeadline)"
'
echo ""
echo "--- Latest commit diff ---"
gh pr view 89 --repo cppalliance/claude-code-chat-browser --json commits | jq -r '.commits[-1].oid' | xargs -I{} git show {} --stat 2>/dev/null || trueLength of output: 1016 🏁 Script executed: #!/bin/bash
# Show the full diff of the latest commit
gh api repos/cppalliance/claude-code-chat-browser/commits/5f1f3262dfaf83b14fb34c59ec0bf148e1dc2ec8 | jq -r '.files[] | "=== \(.filename) ===\n\(.patch)\n"'Length of output: 1586
What your commit does:
That's a clean, well-tested fix that matches exactly what As a bonus, the same commit also switched to |
5f1f326 to
27ef1b7
Compare
Closes #81
Summary
RoleLiteralinmodels/session.pyand narrowMessageDict.rolefromstrto the literal union (user,assistant,system,result,progress).SearchHitDict.roleinmodels/search.py._coerce_role()inutils/jsonl_parser.py: unknown JSONL entry types map to"system"withlogging.warning, never raise.resultentries).RoleLiteralfrommodels/__init__.py.TestUnknownRoleCoercionand update tests that previously expected unknown types to be silently skipped.Test plan
mypy -p api -p utils -p modelsruff check .pytest tests/test_jsonl_parser.py -qpytest -qSummary by CodeRabbit
systemmessages with warnings, including safer fallback extraction and correct behavior forresultandsummary.systemmessage instead of skipping.