Skip to content

feat: add raw CEL mode to routing rule builder with inline error display and round-trip edit support - #5289

Merged
Pratham-Mishra04 merged 1 commit into
devfrom
07-16-feat_routing_rules_cel_expression_validation_front-end
Jul 17, 2026
Merged

feat: add raw CEL mode to routing rule builder with inline error display and round-trip edit support#5289
Pratham-Mishra04 merged 1 commit into
devfrom
07-16-feat_routing_rules_cel_expression_validation_front-end

Conversation

@impoiler

@impoiler impoiler commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Summary

Routing rules authored outside the visual builder (e.g. via the API) carry a raw CEL expression but no query object. Previously, opening such a rule in the edit sheet would silently discard the CEL expression because the builder initialised in visual mode with an empty query. This PR adds a raw CEL editing mode to the conditions editor so those rules can be viewed, edited, and saved without data loss.

Changes

  • Added a Builder | CEL toggle to the CELRuleBuilder component. When in CEL mode, the expression is hand-editable in a textarea and drives onChange directly, bypassing the visual query builder.
  • Rules with a cel_expression but no visual query now open in CEL mode automatically (initialConditionMode helper in routingRuleSheet.tsx).
  • Switching from CEL back to Builder shows a confirmation dialog warning that the hand-written CEL will be discarded (no CEL→query parser exists), and seeds the CEL textarea from the builder's current output when switching the other direction.
  • Server-side CEL compile errors (400 responses) are now surfaced inline beneath the CEL textarea (celError prop) rather than as a toast, keeping the error contextual to the field that caused it.
  • Builder-only validations (regex patterns, rate limit/budget rules) are skipped when in CEL mode, since those inspect the visual query which does not exist in that mode.
  • The info sheet (routingRuleInfoSheet.tsx) now distinguishes between "Matches all requests" and "Defined as a CEL expression below" when a rule has a CEL expression but no visual query.
  • E2E tests cover: creating a rule in raw CEL mode and verifying it round-trips through edit with the expression intact, and rejecting a malformed CEL expression with an inline error while keeping the sheet open and not creating the rule.
  • New page-object helpers: openEditSheet, switchToCelMode, fillCelExpression, getCelTextareaValue, isCelMode, celTextarea, celError.

Type of change

  • Bug fix
  • Feature
  • Refactor
  • Documentation
  • Chore/CI

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (React)
  • Docs

How to test

cd ui
pnpm i
pnpm build

# E2E
pnpm exec playwright test tests/e2e/features/routing-rules/routing-rules.spec.ts
  1. Create a routing rule via the API with a raw CEL expression and no query field.
  2. Open the rule in the UI — it should open in CEL mode with the expression visible in the textarea.
  3. Save without changes — the expression should be preserved after reopening.
  4. Enter a malformed CEL expression (e.g. unbalanced parenthesis) and save — the sheet should stay open and show an inline error beneath the textarea.
  5. Switch from CEL mode to Builder mode with a non-empty expression — a confirmation dialog should appear warning that the CEL will be discarded.

image.png

Breaking changes

  • Yes
  • No

Related issues

Security considerations

No new auth, secrets, or PII surface area introduced. CEL expressions are validated server-side before persistence.

Checklist

  • I read docs/contributing/README.md and followed the guidelines
  • I added/updated tests where appropriate
  • I updated documentation where needed
  • I verified builds succeed (Go and UI)
  • I verified the CI pipeline passes locally if applicable

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in: 52 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 87bafb35-01be-4bf6-a02a-3fda11ac06f7

📥 Commits

Reviewing files that changed from the base of the PR and between 206069d and db30aea.

📒 Files selected for processing (7)
  • tests/e2e/features/routing-rules/pages/routing-rules.page.ts
  • tests/e2e/features/routing-rules/routing-rules.spec.ts
  • ui/app/workspace/routing-rules/components/celBuilder/celRuleBuilder.tsx
  • ui/app/workspace/routing-rules/views/routingRuleInfoSheet.tsx
  • ui/app/workspace/routing-rules/views/routingRuleSheet.tsx
  • ui/components/ui/custom/celBuilder/celRuleBuilder.tsx
  • ui/components/ui/custom/celBuilder/index.ts
📝 Walkthrough

Walkthrough

Routing rules now support visual-builder and raw-CEL condition modes, including mode switching, CEL validation errors, CEL expression persistence, condition display updates, and end-to-end coverage for valid and malformed expressions.

Changes

Routing Rule CEL Editing

Layer / File(s) Summary
Shared CEL builder mode support
ui/components/ui/custom/celBuilder/*
Adds Builder↔CEL mode state, editable expressions, switching controls, discard confirmation, and inline CEL errors.
Routing rule condition mode integration
ui/app/workspace/routing-rules/components/celBuilder/*, ui/app/workspace/routing-rules/views/routingRuleSheet.tsx
Initializes condition mode from saved rules, wires CEL props, skips builder-only validation in CEL mode, and surfaces server errors inline.
Routing rule condition display
ui/app/workspace/routing-rules/views/routingRuleInfoSheet.tsx
Displays whether conditions are defined by a visual query, CEL expression, or neither.
Raw CEL end-to-end coverage
tests/e2e/features/routing-rules/*
Tests valid CEL creation and round-tripping, plus malformed CEL rejection and inline error display.

Estimated code review effort: 4 (Complex) | ~45 minutes

Suggested reviewers: pratham-mishra04

Sequence Diagram(s)

sequenceDiagram
  participant User
  participant RoutingRuleSheet
  participant CELRuleBuilder
  participant RoutingRuleAPI
  User->>CELRuleBuilder: Select CEL mode and enter expression
  CELRuleBuilder->>RoutingRuleSheet: Report mode and CEL text
  User->>RoutingRuleSheet: Submit rule
  RoutingRuleSheet->>RoutingRuleAPI: Save CEL expression
  RoutingRuleAPI-->>RoutingRuleSheet: Return success or compile error
  RoutingRuleSheet-->>User: Close sheet or show inline error
Loading
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main change: adding raw CEL mode, inline error display, and edit round-trip support for routing rules.
Description check ✅ Passed The description covers the required sections and includes summary, changes, test steps, type, affected areas, security, and checklist.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 07-16-feat_routing_rules_cel_expression_validation_front-end

Comment @coderabbitai help to get the list of available commands.

impoiler commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

@impoiler impoiler self-assigned this Jul 16, 2026
@impoiler impoiler changed the title feat: routing Rules CEL expression validation, front-end feat: add raw CEL mode to routing rule builder with inline error display and round-trip edit support Jul 16, 2026
@impoiler
impoiler force-pushed the 07-16-feat_routing_rules_cel_expression_validation_front-end branch from 061b3d2 to 206069d Compare July 16, 2026 08:38
@impoiler
impoiler force-pushed the 07-16-feat_routing_rules_cel_expression_validation_backend branch from 11b071c to 0698f7b Compare July 16, 2026 08:38
@impoiler
impoiler marked this pull request as ready for review July 16, 2026 08:40
@coderabbitai
coderabbitai Bot requested a review from Pratham-Mishra04 July 16, 2026 08:41
@greptile-apps

greptile-apps Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Confidence Score: 5/5

No additional blocking issue qualifies for this follow-up review.

  • No distinct production bug remains to report beyond the existing review feedback.

Important Files Changed

Filename Overview
ui/components/ui/custom/celBuilder/celRuleBuilder.tsx Adds reusable Builder and CEL modes, editable CEL text, mode switching, and inline errors.
ui/app/workspace/routing-rules/views/routingRuleSheet.tsx Integrates raw CEL mode with form initialization, validation, saving, and error handling.
tests/e2e/features/routing-rules/routing-rules.spec.ts Adds coverage for raw CEL creation, edit round trips, and malformed expressions.

Reviews (2): Last reviewed commit: "feat: routing Rules CEL expression valid..." | Re-trigger Greptile

Comment thread ui/components/ui/custom/celBuilder/celRuleBuilder.tsx

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 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 `@ui/components/ui/custom/celBuilder/celRuleBuilder.tsx`:
- Around line 298-312: Update the CEL textarea and conditional error message in
the mode === "cel" branch: assign the error paragraph a stable unique ID,
reference it from Textarea via aria-describedby, and add role="alert" to
announce server-side errors. Preserve the existing conditional rendering and
celError styling.
- Around line 165-189: The mode-switch handlers must no-op when their target
mode is already active. Update switchToCel and requestSwitchToBuilder (or the
button handlers invoking them) to check the current mode before changing text,
state, or opening the discard confirmation, while preserving the existing
conversion and confirmation behavior for actual mode changes.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9e05f1b4-e876-4e3d-9414-f7351fe41838

📥 Commits

Reviewing files that changed from the base of the PR and between 0698f7b and 206069d.

📒 Files selected for processing (7)
  • tests/e2e/features/routing-rules/pages/routing-rules.page.ts
  • tests/e2e/features/routing-rules/routing-rules.spec.ts
  • ui/app/workspace/routing-rules/components/celBuilder/celRuleBuilder.tsx
  • ui/app/workspace/routing-rules/views/routingRuleInfoSheet.tsx
  • ui/app/workspace/routing-rules/views/routingRuleSheet.tsx
  • ui/components/ui/custom/celBuilder/celRuleBuilder.tsx
  • ui/components/ui/custom/celBuilder/index.ts

Comment thread ui/components/ui/custom/celBuilder/celRuleBuilder.tsx
Comment thread ui/components/ui/custom/celBuilder/celRuleBuilder.tsx
coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 16, 2026

Pratham-Mishra04 commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Merge activity

  • Jul 17, 11:09 AM UTC: A user started a stack merge that includes this pull request via Graphite.
  • Jul 17, 11:13 AM UTC: Graphite rebased this pull request as part of a merge.
  • Jul 17, 11:14 AM UTC: @Pratham-Mishra04 merged this pull request with Graphite.

@Pratham-Mishra04
Pratham-Mishra04 changed the base branch from 07-16-feat_routing_rules_cel_expression_validation_backend to graphite-base/5289 July 17, 2026 11:09
@Pratham-Mishra04
Pratham-Mishra04 changed the base branch from graphite-base/5289 to dev July 17, 2026 11:11
@Pratham-Mishra04
Pratham-Mishra04 dismissed coderabbitai[bot]’s stale review July 17, 2026 11:11

The base branch was changed.

@Pratham-Mishra04
Pratham-Mishra04 force-pushed the 07-16-feat_routing_rules_cel_expression_validation_front-end branch from 206069d to db30aea Compare July 17, 2026 11:12
@Pratham-Mishra04
Pratham-Mishra04 merged commit fc459b5 into dev Jul 17, 2026
15 of 16 checks passed
@Pratham-Mishra04
Pratham-Mishra04 deleted the 07-16-feat_routing_rules_cel_expression_validation_front-end branch July 17, 2026 11:14
akshaydeo pushed a commit that referenced this pull request Jul 17, 2026
…lay and round-trip edit support (#5289)

## Summary

Routing rules authored outside the visual builder (e.g. via the API) carry a raw CEL expression but no `query` object. Previously, opening such a rule in the edit sheet would silently discard the CEL expression because the builder initialised in visual mode with an empty query. This PR adds a raw CEL editing mode to the conditions editor so those rules can be viewed, edited, and saved without data loss.

## Changes

- Added a **Builder | CEL toggle** to the `CELRuleBuilder` component. When in CEL mode, the expression is hand-editable in a textarea and drives `onChange` directly, bypassing the visual query builder.
- Rules with a `cel_expression` but no visual `query` now open in CEL mode automatically (`initialConditionMode` helper in `routingRuleSheet.tsx`).
- Switching from CEL back to Builder shows a confirmation dialog warning that the hand-written CEL will be discarded (no CEL→query parser exists), and seeds the CEL textarea from the builder's current output when switching the other direction.
- Server-side CEL compile errors (400 responses) are now surfaced inline beneath the CEL textarea (`celError` prop) rather than as a toast, keeping the error contextual to the field that caused it.
- Builder-only validations (regex patterns, rate limit/budget rules) are skipped when in CEL mode, since those inspect the visual query which does not exist in that mode.
- The info sheet (`routingRuleInfoSheet.tsx`) now distinguishes between "Matches all requests" and "Defined as a CEL expression below" when a rule has a CEL expression but no visual query.
- E2E tests cover: creating a rule in raw CEL mode and verifying it round-trips through edit with the expression intact, and rejecting a malformed CEL expression with an inline error while keeping the sheet open and not creating the rule.
- New page-object helpers: `openEditSheet`, `switchToCelMode`, `fillCelExpression`, `getCelTextareaValue`, `isCelMode`, `celTextarea`, `celError`.

## Type of change

- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [ ] Core (Go)
- [ ] Transports (HTTP)
- [ ] Providers/Integrations
- [ ] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

```sh
cd ui
pnpm i
pnpm build

# E2E
pnpm exec playwright test tests/e2e/features/routing-rules/routing-rules.spec.ts
```

1. Create a routing rule via the API with a raw CEL expression and no `query` field.
2. Open the rule in the UI — it should open in CEL mode with the expression visible in the textarea.
3. Save without changes — the expression should be preserved after reopening.
4. Enter a malformed CEL expression (e.g. unbalanced parenthesis) and save — the sheet should stay open and show an inline error beneath the textarea.
5. Switch from CEL mode to Builder mode with a non-empty expression — a confirmation dialog should appear warning that the CEL will be discarded.

  
  
![image.png](https://app.graphite.com/user-attachments/assets/3a2515aa-ca27-4eda-b3f0-de0ef215bc65.png)





## Breaking changes

- [ ] Yes
- [x] No

## Related issues

## Security considerations

No new auth, secrets, or PII surface area introduced. CEL expressions are validated server-side before persistence.

## Checklist

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
akshaydeo pushed a commit that referenced this pull request Jul 18, 2026
…lay and round-trip edit support (#5289)

## Summary

Routing rules authored outside the visual builder (e.g. via the API) carry a raw CEL expression but no `query` object. Previously, opening such a rule in the edit sheet would silently discard the CEL expression because the builder initialised in visual mode with an empty query. This PR adds a raw CEL editing mode to the conditions editor so those rules can be viewed, edited, and saved without data loss.

## Changes

- Added a **Builder | CEL toggle** to the `CELRuleBuilder` component. When in CEL mode, the expression is hand-editable in a textarea and drives `onChange` directly, bypassing the visual query builder.
- Rules with a `cel_expression` but no visual `query` now open in CEL mode automatically (`initialConditionMode` helper in `routingRuleSheet.tsx`).
- Switching from CEL back to Builder shows a confirmation dialog warning that the hand-written CEL will be discarded (no CEL→query parser exists), and seeds the CEL textarea from the builder's current output when switching the other direction.
- Server-side CEL compile errors (400 responses) are now surfaced inline beneath the CEL textarea (`celError` prop) rather than as a toast, keeping the error contextual to the field that caused it.
- Builder-only validations (regex patterns, rate limit/budget rules) are skipped when in CEL mode, since those inspect the visual query which does not exist in that mode.
- The info sheet (`routingRuleInfoSheet.tsx`) now distinguishes between "Matches all requests" and "Defined as a CEL expression below" when a rule has a CEL expression but no visual query.
- E2E tests cover: creating a rule in raw CEL mode and verifying it round-trips through edit with the expression intact, and rejecting a malformed CEL expression with an inline error while keeping the sheet open and not creating the rule.
- New page-object helpers: `openEditSheet`, `switchToCelMode`, `fillCelExpression`, `getCelTextareaValue`, `isCelMode`, `celTextarea`, `celError`.

## Type of change

- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [ ] Core (Go)
- [ ] Transports (HTTP)
- [ ] Providers/Integrations
- [ ] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

```sh
cd ui
pnpm i
pnpm build

# E2E
pnpm exec playwright test tests/e2e/features/routing-rules/routing-rules.spec.ts
```

1. Create a routing rule via the API with a raw CEL expression and no `query` field.
2. Open the rule in the UI — it should open in CEL mode with the expression visible in the textarea.
3. Save without changes — the expression should be preserved after reopening.
4. Enter a malformed CEL expression (e.g. unbalanced parenthesis) and save — the sheet should stay open and show an inline error beneath the textarea.
5. Switch from CEL mode to Builder mode with a non-empty expression — a confirmation dialog should appear warning that the CEL will be discarded.

  
  
![image.png](https://app.graphite.com/user-attachments/assets/3a2515aa-ca27-4eda-b3f0-de0ef215bc65.png)





## Breaking changes

- [ ] Yes
- [x] No

## Related issues

## Security considerations

No new auth, secrets, or PII surface area introduced. CEL expressions are validated server-side before persistence.

## Checklist

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
@coderabbitai coderabbitai Bot mentioned this pull request Jul 24, 2026
18 tasks
akhsaul pushed a commit to akhsaul/bifrost that referenced this pull request Aug 27, 2026
…lay and round-trip edit support (maximhq#5289)

## Summary

Routing rules authored outside the visual builder (e.g. via the API) carry a raw CEL expression but no `query` object. Previously, opening such a rule in the edit sheet would silently discard the CEL expression because the builder initialised in visual mode with an empty query. This PR adds a raw CEL editing mode to the conditions editor so those rules can be viewed, edited, and saved without data loss.

## Changes

- Added a **Builder | CEL toggle** to the `CELRuleBuilder` component. When in CEL mode, the expression is hand-editable in a textarea and drives `onChange` directly, bypassing the visual query builder.
- Rules with a `cel_expression` but no visual `query` now open in CEL mode automatically (`initialConditionMode` helper in `routingRuleSheet.tsx`).
- Switching from CEL back to Builder shows a confirmation dialog warning that the hand-written CEL will be discarded (no CEL→query parser exists), and seeds the CEL textarea from the builder's current output when switching the other direction.
- Server-side CEL compile errors (400 responses) are now surfaced inline beneath the CEL textarea (`celError` prop) rather than as a toast, keeping the error contextual to the field that caused it.
- Builder-only validations (regex patterns, rate limit/budget rules) are skipped when in CEL mode, since those inspect the visual query which does not exist in that mode.
- The info sheet (`routingRuleInfoSheet.tsx`) now distinguishes between "Matches all requests" and "Defined as a CEL expression below" when a rule has a CEL expression but no visual query.
- E2E tests cover: creating a rule in raw CEL mode and verifying it round-trips through edit with the expression intact, and rejecting a malformed CEL expression with an inline error while keeping the sheet open and not creating the rule.
- New page-object helpers: `openEditSheet`, `switchToCelMode`, `fillCelExpression`, `getCelTextareaValue`, `isCelMode`, `celTextarea`, `celError`.

## Type of change

- [ ] Bug fix
- [x] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Chore/CI

## Affected areas

- [ ] Core (Go)
- [ ] Transports (HTTP)
- [ ] Providers/Integrations
- [ ] Plugins
- [x] UI (React)
- [ ] Docs

## How to test

```sh
cd ui
pnpm i
pnpm build

# E2E
pnpm exec playwright test tests/e2e/features/routing-rules/routing-rules.spec.ts
```

1. Create a routing rule via the API with a raw CEL expression and no `query` field.
2. Open the rule in the UI — it should open in CEL mode with the expression visible in the textarea.
3. Save without changes — the expression should be preserved after reopening.
4. Enter a malformed CEL expression (e.g. unbalanced parenthesis) and save — the sheet should stay open and show an inline error beneath the textarea.
5. Switch from CEL mode to Builder mode with a non-empty expression — a confirmation dialog should appear warning that the CEL will be discarded.

  
  
![image.png](https://app.graphite.com/user-attachments/assets/3a2515aa-ca27-4eda-b3f0-de0ef215bc65.png)





## Breaking changes

- [ ] Yes
- [x] No

## Related issues

## Security considerations

No new auth, secrets, or PII surface area introduced. CEL expressions are validated server-side before persistence.

## Checklist

- [x] I read `docs/contributing/README.md` and followed the guidelines
- [x] I added/updated tests where appropriate
- [ ] I updated documentation where needed
- [x] I verified builds succeed (Go and UI)
- [ ] I verified the CI pipeline passes locally if applicable
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants