feat(ui): add complexity router config UI and CEL support#3715
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:
📝 WalkthroughWalkthroughAdds a Complexity Router feature: types and defaults, governance RTK Query endpoints and cache tag, a validated react-hook-form page with TierSpectrumBar and keyword editors, a routing-rule field, RBAC-guarded route, and a sidebar link. ChangesComplexity Router Configuration
sequenceDiagram
participant User
participant ComplexityRouterPage
participant RTKQuery
participant Backend
User->>ComplexityRouterPage: Load page
ComplexityRouterPage->>RTKQuery: useGetComplexityAnalyzerConfigQuery()
RTKQuery->>Backend: GET /governance/complexity-analyzer-config
Backend-->>RTKQuery: AnalyzerConfig { tier_boundaries, keywords }
RTKQuery-->>ComplexityRouterPage: Config data
ComplexityRouterPage->>ComplexityRouterPage: Initialize form with fetched config
ComplexityRouterPage->>User: Render TierSpectrumBar + inputs + keyword lists
User->>ComplexityRouterPage: Edit inputs
ComplexityRouterPage->>ComplexityRouterPage: Validate with Zod
User->>ComplexityRouterPage: Save
ComplexityRouterPage->>RTKQuery: useUpdateComplexityAnalyzerConfigMutation()
RTKQuery->>Backend: PUT /governance/complexity-analyzer-config
Backend-->>RTKQuery: Updated config
RTKQuery-->>ComplexityRouterPage: Success + invalidate ComplexityAnalyzerConfig
User->>ComplexityRouterPage: Restore defaults
ComplexityRouterPage->>User: Show AlertDialog
User->>ComplexityRouterPage: Confirm
ComplexityRouterPage->>RTKQuery: useResetComplexityAnalyzerConfigMutation()
RTKQuery->>Backend: POST /governance/complexity-analyzer-config/reset
Backend-->>RTKQuery: Factory defaults
RTKQuery-->>ComplexityRouterPage: Success + invalidate ComplexityAnalyzerConfig
ComplexityRouterPage->>ComplexityRouterPage: Reset form to defaults
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 1 | ❌ 4❌ Failed checks (4 warnings)
✅ Passed checks (1 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
Confidence Score: 5/5Safe to merge — purely additive UI and API wiring with no changes to existing logic. All mutations are guarded by a write RBAC check both at the button-disable level and inside the submit/reset handlers. Form validation, error states, loading states, and the spectrum bar preview are all handled correctly. The RTK Query tag registration and invalidation are consistent with the rest of the governance API slice. No pre-existing data or routes are modified. No files require special attention. Important Files Changed
Reviews (20): Last reviewed commit: "feat(ui): add complexity router config U..." | Re-trigger Greptile |
There was a problem hiding this comment.
Actionable comments posted: 3
🤖 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/app/workspace/complexity-router/page.tsx`:
- Line 389: The current data-testid uses display labels (e.g.,
data-testid={`${label}-input`}) and several interactive controls are missing
test IDs; update all new interactive elements in this component to use the
convention-based stable selectors "entity-element-qualifier" (e.g.,
"complexity-filter-input" or "complexity-sort-button") instead of interpolated
display text, replace usages of data-testid={`${label}-input`} (and similar
constructs) with explicit, hard-coded test ids derived from the entity name and
element role, and add matching data-testid attributes to every interactive
control rendered in this file (inputs, buttons, selects, toggles) so E2E tests
can reliably target them; use the variable name 'label' only for display, not
for test ids, and ensure each new control has a unique id/testid following the
convention.
In `@ui/lib/store/apis/governanceApi.ts`:
- Around line 811-826: Replace the tag-based cache invalidation for
updateComplexityAnalyzerConfig and resetComplexityAnalyzerConfig with optimistic
cache updates using onQueryStarted: in both mutations
(updateComplexityAnalyzerConfig and resetComplexityAnalyzerConfig) add an
onQueryStarted handler that awaits the mutation, then call
governanceApi.util.updateQueryData for the getComplexityAnalyzerConfig cache to
apply the returned AnalyzerConfig (or patch/reset values) and roll back on
error; reference governanceApi.util.updateQueryData and
getComplexityAnalyzerConfig to locate the target cache entry and use the
mutation response to update it instead of relying on invalidatesTags:
["ComplexityAnalyzerConfig"].
In `@ui/lib/types/complexityRouter.ts`:
- Around line 1-4: Update the header docblock in
ui/lib/types/complexityRouter.ts to reference the correct API path used by this
feature: replace "/api/governance/complexity" with
"/governance/complexity-analyzer-config" so the Complexity Router type
definitions mirror the actual contract; edit the top-of-file comment that
currently says "Mirrors the AnalyzerConfig shape exchanged with
/api/governance/complexity" to use the correct endpoint string.
🪄 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: 24adb8df-56e2-4a07-90a5-36b9b3d19b73
📒 Files selected for processing (7)
ui/app/workspace/complexity-router/layout.tsxui/app/workspace/complexity-router/page.tsxui/components/sidebar.tsxui/lib/config/celFieldsRouting.tsui/lib/store/apis/baseApi.tsui/lib/store/apis/governanceApi.tsui/lib/types/complexityRouter.ts
0dbc48b to
88e2f0e
Compare
d56b305 to
5cc4920
Compare
There was a problem hiding this comment.
Actionable comments posted: 1
♻️ Duplicate comments (1)
ui/lib/store/apis/governanceApi.ts (1)
811-826: 🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick winUse
onQueryStarted+updateQueryDatafor optimistic cache updatesThe mutations use
invalidatesTags, but other governance mutations in this file useonQueryStarted+governanceApi.util.updateQueryDatato avoid stale UI in clustered deployments.Proposed refactor
updateComplexityAnalyzerConfig: builder.mutation<AnalyzerConfig, AnalyzerConfig>({ query: (data) => ({ url: "/governance/complexity-analyzer-config", method: "PUT", body: data, }), - invalidatesTags: ["ComplexityAnalyzerConfig"], + async onQueryStarted(_arg, { dispatch, queryFulfilled }) { + try { + const { data } = await queryFulfilled; + dispatch( + governanceApi.util.updateQueryData("getComplexityAnalyzerConfig", undefined, (draft) => { + Object.assign(draft, data); + }), + ); + } catch { + // Mutation failed + } + }, }), resetComplexityAnalyzerConfig: builder.mutation<AnalyzerConfig, void>({ query: () => ({ url: "/governance/complexity-analyzer-config/reset", method: "POST", }), - invalidatesTags: ["ComplexityAnalyzerConfig"], + async onQueryStarted(_arg, { dispatch, queryFulfilled }) { + try { + const { data } = await queryFulfilled; + dispatch( + governanceApi.util.updateQueryData("getComplexityAnalyzerConfig", undefined, (draft) => { + Object.assign(draft, data); + }), + ); + } catch { + // Mutation failed + } + }, }),Based on learnings: In ui/lib/store/apis/, optimistically patch the cache with onQueryStarted + updateQueryData for mutations instead of using invalidatesTags to avoid cross-server stale UI in clustered environments.
🤖 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 `@ui/lib/store/apis/governanceApi.ts` around lines 811 - 826, Replace the current invalidatesTags-based approach for updateComplexityAnalyzerConfig and resetComplexityAnalyzerConfig with optimistic cache updates by adding an onQueryStarted handler that uses governanceApi.util.updateQueryData to patch the cached "ComplexityAnalyzerConfig" query; in onQueryStarted, apply the incoming change to the cached AnalyzerConfig immediately, rollback on error, and finalize on queryFulfilled to ensure UI stays consistent across clustered deployments.
🧹 Nitpick comments (1)
ui/lib/config/celFieldsRouting.ts (1)
115-124: ⚡ Quick winConsider adding a description field for user clarity.
The
complexity_tierfield definition could benefit from adescriptionproperty (similar torequest_type,tokens_used, etc.) to help users understand when and how to use this filter in routing rules.💡 Suggested addition
{ name: "complexity_tier", label: "Complexity Tier", placeholder: "Select complexity tier", inputType: "select", valueEditorType: "select", operators: ["=", "!=", "in", "notIn"], defaultOperator: "=", values: COMPLEXITY_TIER_VALUES.map((tier) => ({ name: tier, label: tier })), + description: "Route requests based on their computed complexity tier", },🤖 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 `@ui/lib/config/celFieldsRouting.ts` around lines 115 - 124, Add a descriptive "description" property to the field object whose name is "complexity_tier" so users understand the purpose and usage of this filter in routing rules; mirror the style and phrasing used by similar fields like "request_type" or "tokens_used" (e.g., brief explanation of what "complexity tier" represents and when to use it) and place it alongside existing keys (name, label, placeholder, inputType, valueEditorType, operators, defaultOperator, values) in the same object.
🤖 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/app/workspace/complexity-router/page.tsx`:
- Around line 264-269: The effect unconditionally calls reset(data) on every
background refetch which can wipe user edits; change it to only reset when there
are no in-progress edits by using the form's dirty flag (e.g. formState.isDirty
or isDirty from useForm). Update the effect that currently references
useEffect/data/reset/setSubmitError so it checks if (data && !formState.isDirty)
{ reset(data); setSubmitError(null); } and add formState.isDirty (or isDirty) to
the dependency array to avoid losing user-entered values on refetch.
---
Duplicate comments:
In `@ui/lib/store/apis/governanceApi.ts`:
- Around line 811-826: Replace the current invalidatesTags-based approach for
updateComplexityAnalyzerConfig and resetComplexityAnalyzerConfig with optimistic
cache updates by adding an onQueryStarted handler that uses
governanceApi.util.updateQueryData to patch the cached
"ComplexityAnalyzerConfig" query; in onQueryStarted, apply the incoming change
to the cached AnalyzerConfig immediately, rollback on error, and finalize on
queryFulfilled to ensure UI stays consistent across clustered deployments.
---
Nitpick comments:
In `@ui/lib/config/celFieldsRouting.ts`:
- Around line 115-124: Add a descriptive "description" property to the field
object whose name is "complexity_tier" so users understand the purpose and usage
of this filter in routing rules; mirror the style and phrasing used by similar
fields like "request_type" or "tokens_used" (e.g., brief explanation of what
"complexity tier" represents and when to use it) and place it alongside existing
keys (name, label, placeholder, inputType, valueEditorType, operators,
defaultOperator, values) in the same 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: ac53c6d2-40de-47ac-9b8c-e95cf5987e37
📒 Files selected for processing (7)
ui/app/workspace/complexity-router/layout.tsxui/app/workspace/complexity-router/page.tsxui/components/sidebar.tsxui/lib/config/celFieldsRouting.tsui/lib/store/apis/baseApi.tsui/lib/store/apis/governanceApi.tsui/lib/types/complexityRouter.ts
✅ Files skipped from review due to trivial changes (1)
- ui/lib/store/apis/baseApi.ts
5cc4920 to
3a08ff0
Compare
34d7901 to
92c82f1
Compare
3d09d45 to
b66e714
Compare
92c82f1 to
b2756f5
Compare
There was a problem hiding this comment.
♻️ Duplicate comments (1)
ui/app/workspace/complexity-router/page.tsx (1)
264-269:⚠️ Potential issue | 🟠 Major | ⚡ Quick winPrevent unintended form data loss on background refetch.
This effect resets form state every time query
datachanges, which can wipe in-progress edits if the query is invalidated/refetched while the user is editing.Suggested fix
useEffect(() => { - if (data) { + if (data && !isDirty) { reset(data); setSubmitError(null); } -}, [data, reset]); +}, [data, isDirty, reset]);
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7c53e8a6-c6dc-47ad-ac5a-22b5b5507c31
📒 Files selected for processing (7)
ui/app/workspace/complexity-router/layout.tsxui/app/workspace/complexity-router/page.tsxui/components/sidebar.tsxui/lib/config/celFieldsRouting.tsui/lib/store/apis/baseApi.tsui/lib/store/apis/governanceApi.tsui/lib/types/complexityRouter.ts
✅ Files skipped from review due to trivial changes (1)
- ui/lib/store/apis/baseApi.ts
b2756f5 to
d7bff03
Compare
5b4a4bd to
dfd376e
Compare
5f16493 to
bad96f1
Compare
dfd376e to
023fe4b
Compare
bad96f1 to
444fe9a
Compare
023fe4b to
24b4cdf
Compare
444fe9a to
deb50b7
Compare
9ffc142 to
0bae999
Compare
00d7bee to
7e06261
Compare
0bae999 to
3b8e6cd
Compare
7e06261 to
aa8c316
Compare
3b8e6cd to
89303f9
Compare
aa8c316 to
8377b5a
Compare
89303f9 to
1d1c7e7
Compare
1d1c7e7 to
a149544
Compare
8377b5a to
87b2afc
Compare
87b2afc to
feb5264
Compare
887b9fc to
0f24388
Compare
feb5264 to
4d0a27b
Compare
0f24388 to
c1f0650
Compare
Merge activity
|
The base branch was changed.
## Summary Briefly explain the purpose of this PR and the problem it solves. ## Changes - What was changed and why - Any notable design decisions or trade-offs ## 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 Describe the steps to validate this change. Include commands and expected outcomes. ```sh # Core/Transports go version go test ./... # UI cd ui pnpm i || npm i pnpm test || npm test pnpm build || npm run build ``` If adding new configs or environment variables, document them here. ## Screenshots/Recordings If UI changes, add before/after screenshots or short clips. ## Breaking changes - [ ] Yes - [ ] No If yes, describe impact and migration instructions. ## Related issues Link related issues and discussions. Example: Closes maximhq#123 ## Security considerations Note any security implications (auth, secrets, PII, sandboxing, etc.). ## 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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Added new Complexity Router management page for configuring request complexity classification into four customizable tiers * Users can set boundary thresholds and define keyword lists for each tier level * Includes options to save changes, discard edits, and restore factory defaults * Accessible via the sidebar under the Routing Rules section with role-based access control <!-- end of auto-generated comment: release notes by coderabbit.ai -->
## Summary Briefly explain the purpose of this PR and the problem it solves. ## Changes - What was changed and why - Any notable design decisions or trade-offs ## 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 Describe the steps to validate this change. Include commands and expected outcomes. ```sh # Core/Transports go version go test ./... # UI cd ui pnpm i || npm i pnpm test || npm test pnpm build || npm run build ``` If adding new configs or environment variables, document them here. ## Screenshots/Recordings If UI changes, add before/after screenshots or short clips. ## Breaking changes - [ ] Yes - [ ] No If yes, describe impact and migration instructions. ## Related issues Link related issues and discussions. Example: Closes #123 ## Security considerations Note any security implications (auth, secrets, PII, sandboxing, etc.). ## 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 <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes * **New Features** * Added new Complexity Router management page for configuring request complexity classification into four customizable tiers * Users can set boundary thresholds and define keyword lists for each tier level * Includes options to save changes, discard edits, and restore factory defaults * Accessible via the sidebar under the Routing Rules section with role-based access control <!-- end of auto-generated comment: release notes by coderabbit.ai -->

Summary
Briefly explain the purpose of this PR and the problem it solves.
Changes
Type of change
Affected areas
How to test
Describe the steps to validate this change. Include commands and expected outcomes.
If adding new configs or environment variables, document them here.
Screenshots/Recordings
If UI changes, add before/after screenshots or short clips.
Breaking changes
If yes, describe impact and migration instructions.
Related issues
Link related issues and discussions. Example: Closes #123
Security considerations
Note any security implications (auth, secrets, PII, sandboxing, etc.).
Checklist
docs/contributing/README.mdand followed the guidelinesSummary by CodeRabbit
Release Notes