feat(widget): add redirect support to quick-reply pills#836
feat(widget): add redirect support to quick-reply pills#836amreetkhuntia wants to merge 1 commit into
Conversation
|
Important Review skippedAuto incremental reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughAdds ChangesQuick-reply open_url redirect feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
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 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.
Actionable comments posted: 2
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
.gitignore (1)
53-58:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winResolve comment-vs-rule conflict for
.claude/settings.json.Line 53 says
settings.jsonshould be shared, but Line 57 now ignores it. Either remove the ignore entry or update the comment to reflect the intended policy.🤖 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 @.gitignore around lines 53 - 58, There is a contradiction in the .gitignore file between the comment on line 53 and the actual ignore rules. The comment states that settings.json should be shared with the team, but line 57 contains .claude/settings.json as an ignore entry, which prevents it from being tracked. To resolve this conflict, either remove the .claude/settings.json ignore entry from line 57 to allow the file to be shared as the comment indicates, or update the comment on line 53 to accurately reflect that settings.json is kept local and should not be shared. Choose the approach that aligns with your intended policy for this configuration file.
🧹 Nitpick comments (2)
app/ai/voice/agents/breeze_buddy/template/ui_prompt.py (1)
92-99: ⚡ Quick winUpdate the shared action footer to reflect
targetsupport (new_tab/same_tab).This change introduces
target, but the footer still documentsopen_urlas “new tab” only. Keeping footer + schema aligned will prevent prompt-level drift.💡 Suggested fix
_FOOTER = ( "Action shape (embedded inside Button/Tile/Handoff):\n" ' {type:"to_assistant", msg*: string} — re-enter the chat as if ' "the user typed `msg`\n" - ' {type:"open_url", url*: HttpUrl} — open a URL in a new tab\n' + ' {type:"open_url", url*: HttpUrl, target?: "new_tab"|"same_tab"}' + " — open a URL (default new_tab)\n"🤖 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 `@app/ai/voice/agents/breeze_buddy/template/ui_prompt.py` around lines 92 - 99, The code now supports a `target` parameter in the `open_url` action that can be either `new_tab` or `same_tab`, but the shared action footer documentation still describes `open_url` as opening in a new tab only. Locate the footer or schema documentation for the `open_url` action (likely a string constant or docstring describing available actions) and update it to document the `target` parameter with both supported values (`new_tab` and `same_tab`) so the documentation stays aligned with the actual implementation.tests/test_quick_reply_redirect.py (1)
33-150: ⚡ Quick winAdd return type hints to test function signatures to match repo typing policy.
The new test/helper functions are unannotated; adding explicit return types (e.g.,
-> None, helper return types) keeps this file aligned with the project-wide typing guideline.As per coding guidelines,
**/*.py: “Add type hints on all function signatures”.🤖 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 `@tests/test_quick_reply_redirect.py` around lines 33 - 150, All test functions and helper functions in this file are missing return type hints, which violates the project's typing guidelines. Add return type annotations to every function definition: add `-> None` as the return type for all test functions (test_open_url_defaults_to_new_tab, test_open_url_accepts_same_tab, test_open_url_rejects_unknown_target, test_quick_replies_with_redirect_action_validates, test_quick_reply_item_without_action_is_backward_compatible, test_quick_reply_item_accepts_to_assistant_action, test_static_option_redirect_needs_no_value, test_static_option_without_action_is_backward_compatible, test_wire_carries_action_with_null_value, test_handler_message_pill_falls_back_to_label, test_handler_redirect_pill_has_null_value_and_passes_action, and test_handler_no_configurations_returns_defaults), and add an appropriate return type annotation for the _template_with_quick_replies helper function based on what it returns (a SimpleNamespace object).Source: Coding guidelines
🤖 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 `@app/api/routers/breeze_buddy/widget/handlers.py`:
- Around line 164-171: The value assignment logic for pills in this code needs
to prioritize redirect action checks. Currently, when qr.value is not None, it
is used regardless of whether the action is a redirect (open_url). To fix this,
reverse the conditional order: first check if the action is a redirect using
_is_redirect_action(qr.action), and if true, always set value to None. Only if
it is not a redirect action should the existing fallback logic apply (use
qr.value if present, otherwise use qr.label). This ensures redirect pills never
leak message value semantics to clients.
In `@tests/test_quick_reply_redirect.py`:
- Around line 44-47: The test file has type checking issues where assertions
access action attributes on optional fields without proper type narrowing. Fix
this by casting the results of validate_props() calls to the specific
QuickReplies type (using cast() from typing), and before accessing any
attributes on the optional .action field, add either isinstance() checks to
narrow the union type or assert statements to ensure the field is not None.
Apply these guards consistently wherever .action.type or .action.target are
accessed in assertions throughout the test file.
---
Outside diff comments:
In @.gitignore:
- Around line 53-58: There is a contradiction in the .gitignore file between the
comment on line 53 and the actual ignore rules. The comment states that
settings.json should be shared with the team, but line 57 contains
.claude/settings.json as an ignore entry, which prevents it from being tracked.
To resolve this conflict, either remove the .claude/settings.json ignore entry
from line 57 to allow the file to be shared as the comment indicates, or update
the comment on line 53 to accurately reflect that settings.json is kept local
and should not be shared. Choose the approach that aligns with your intended
policy for this configuration file.
---
Nitpick comments:
In `@app/ai/voice/agents/breeze_buddy/template/ui_prompt.py`:
- Around line 92-99: The code now supports a `target` parameter in the
`open_url` action that can be either `new_tab` or `same_tab`, but the shared
action footer documentation still describes `open_url` as opening in a new tab
only. Locate the footer or schema documentation for the `open_url` action
(likely a string constant or docstring describing available actions) and update
it to document the `target` parameter with both supported values (`new_tab` and
`same_tab`) so the documentation stays aligned with the actual implementation.
In `@tests/test_quick_reply_redirect.py`:
- Around line 33-150: All test functions and helper functions in this file are
missing return type hints, which violates the project's typing guidelines. Add
return type annotations to every function definition: add `-> None` as the
return type for all test functions (test_open_url_defaults_to_new_tab,
test_open_url_accepts_same_tab, test_open_url_rejects_unknown_target,
test_quick_replies_with_redirect_action_validates,
test_quick_reply_item_without_action_is_backward_compatible,
test_quick_reply_item_accepts_to_assistant_action,
test_static_option_redirect_needs_no_value,
test_static_option_without_action_is_backward_compatible,
test_wire_carries_action_with_null_value,
test_handler_message_pill_falls_back_to_label,
test_handler_redirect_pill_has_null_value_and_passes_action, and
test_handler_no_configurations_returns_defaults), and add an appropriate return
type annotation for the _template_with_quick_replies helper function based on
what it returns (a SimpleNamespace object).
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 2cae9095-4a65-4c39-b31b-50e8d56689fb
📒 Files selected for processing (7)
.gitignoreapp/ai/voice/agents/breeze_buddy/template/types.pyapp/ai/voice/agents/breeze_buddy/template/ui_catalog.pyapp/ai/voice/agents/breeze_buddy/template/ui_prompt.pyapp/api/routers/breeze_buddy/widget/handlers.pyapp/schemas/breeze_buddy/chat.pytests/test_quick_reply_redirect.py
| label=qr.label, | ||
| # Redirect pills (open_url action) don't message the agent, so the | ||
| # label->value fallback only applies to plain message pills. | ||
| value=( | ||
| qr.value | ||
| if qr.value is not None | ||
| else (None if _is_redirect_action(qr.action) else qr.label) | ||
| ), |
There was a problem hiding this comment.
Force redirect pills to always emit value=None.
Line 167 currently keeps qr.value when present, even for open_url actions. That conflicts with the redirect wire behavior in this PR and can leak message semantics back to clients that still key off value.
💡 Suggested fix
QuickReplyWire(
label=qr.label,
# Redirect pills (open_url action) don't message the agent, so the
# label->value fallback only applies to plain message pills.
- value=(
- qr.value
- if qr.value is not None
- else (None if _is_redirect_action(qr.action) else qr.label)
- ),
+ value=(
+ None
+ if _is_redirect_action(qr.action)
+ else (qr.value if qr.value is not None else qr.label)
+ ),
action=qr.action,
)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| label=qr.label, | |
| # Redirect pills (open_url action) don't message the agent, so the | |
| # label->value fallback only applies to plain message pills. | |
| value=( | |
| qr.value | |
| if qr.value is not None | |
| else (None if _is_redirect_action(qr.action) else qr.label) | |
| ), | |
| label=qr.label, | |
| # Redirect pills (open_url action) don't message the agent, so the | |
| # label->value fallback only applies to plain message pills. | |
| value=( | |
| None | |
| if _is_redirect_action(qr.action) | |
| else (qr.value if qr.value is not None else qr.label) | |
| ), |
🤖 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 `@app/api/routers/breeze_buddy/widget/handlers.py` around lines 164 - 171, The
value assignment logic for pills in this code needs to prioritize redirect
action checks. Currently, when qr.value is not None, it is used regardless of
whether the action is a redirect (open_url). To fix this, reverse the
conditional order: first check if the action is a redirect using
_is_redirect_action(qr.action), and if true, always set value to None. Only if
it is not a redirect action should the existing fallback logic apply (use
qr.value if present, otherwise use qr.label). This ensures redirect pills never
leak message value semantics to clients.
810e24f to
1d912d1
Compare
Quick-reply chicklets could only send their value back to the agent. A pill can now optionally carry an action, reusing the catalog's existing ActionUnion: an open_url action makes the pill redirect (honoring a new target: new_tab|same_tab) instead of messaging the agent. - ui_catalog: OpenUrlAction gains target; QuickReplyItem gains action - ui_prompt: add a redirect example so the LLM can emit redirect pills - types: QuickReplyOption (static config chicklets) gains action - chat schema: QuickReplyWire carries action to the frontend - widget handler: pass action through; only apply the value=label fallback for message pills (redirect pills have null value) Backward compatible: action defaults to None (existing send-to-agent behavior), target defaults to new_tab. JSONB column, no migration. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1d912d1 to
9185341
Compare
PR #836 —
|
Quick-reply chicklets could only send their value back to the agent. A pill can now optionally carry an action, reusing the catalog's existing ActionUnion: an open_url action makes the pill redirect (honoring a new target: new_tab|same_tab) instead of messaging the agent.
Backward compatible: action defaults to None (existing send-to-agent behavior), target defaults to new_tab. JSONB column, no migration.
Summary by CodeRabbit
New Features
Tests