Skip to content

semantic router ui revamp - #5865

Closed
kohlivrinda wants to merge 1 commit into
08-04-configstore_adds_default_exemplers_in_existing_complexity_config_tiersfrom
08-05-semantic_router_ui_revamp
Closed

semantic router ui revamp#5865
kohlivrinda wants to merge 1 commit into
08-04-configstore_adds_default_exemplers_in_existing_complexity_config_tiersfrom
08-05-semantic_router_ui_revamp

Conversation

@kohlivrinda

@kohlivrinda kohlivrinda commented Aug 5, 2026

Copy link
Copy Markdown
Member

Summary

Simplifies the Complexity Router to be semantic-only, removing the lexical/semantic mode toggle and making embedding-based classification the single path. The page now treats phrase lists as reference phrases for the semantic classifier rather than dual-purpose keyword/exemplar lists, and the backend merges editable phrases onto the built-in keyword vocabulary instead of replacing it.

Changes

  • Removed lexical/semantic mode toggle: The page no longer has a ClassificationMode state or tab switcher. Semantic classification is the only offered mode; the lexical scorer still runs internally but is no longer user-facing.
  • Editable phrase lists are now exemplars-only: DefaultEditableKeywordConfig returns only the semantic exemplars from configstore, not the combined keyword+exemplar list. The lexical scorer's built-in vocabulary is kept out of the administrator-facing lists.
  • mergeEditableKeywordsOntoDefaults now adds to built-ins: Instead of replacing a tier's keyword list when the editable list is non-empty, it appends the editable phrases onto the built-in vocabulary, deduplicating by normalized key. This prevents the lexical scorer from silently losing its short-word signals when only sentence-length exemplars are present.
  • sharedTierDefaults deduplicates: The helper now tracks seen entries (lowercased, trimmed) and skips duplicates when merging extra phrases onto a base list.
  • Tier boundary controls removed from the UI: Boundaries are carried through the form untouched and validated only for structural correctness. An out-of-range persisted value falls back to defaults rather than blocking every save.
  • Fallback option removed: The fallback: "lexical" option is no longer offered. Configs carrying it are normalized to "none" on the next save. The external vector store option is similarly hidden; persisted values are presented and re-saved as "auto".
  • SemanticStatusPanel updated: Reflects the new single-mode design — shows "Not configured" when no provider/model is set, and consolidates the failed-state messaging to a single callout regardless of fallback setting.
  • TagInput collapse behavior changed from count-based to height-based: collapsedTagLimit replaced by collapsedMaxHeight (px). A ResizeObserver measures actual rendered height so columns of different-length phrases collapse to the same visual size. The expand/collapse toggle is a single button that switches label rather than two separate buttons.
  • Layout fix for sticky footer: The page now uses a flex column with a ScrollArea sibling rather than a sticky child inside a Radix scroll container, which was unreliable inside display:table boxes. A @layer utilities rule with .own-scroll-parent overrides the shell's overflow: auto !important to prevent a double scrollbar.
  • UI copy updated throughout: "Keywords" → "phrases", "exemplars" → "reference phrases", section headings reorganized to Phrase to Tier Mapping → Classifier Status → Embedding Configuration.
  • InfoTip, FieldLabel, Callout, and SectionHeading components extracted: Inline description paragraphs replaced with tooltip-bearing labels and callout boxes to reduce visual noise.

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

# Backend
go test ./plugins/governance/complexity/...

# UI
cd ui
pnpm i
pnpm build
  1. Open the Complexity Router page. Confirm there is no lexical/semantic toggle and the page shows Phrase to Tier Mapping, Classifier Status, and Embedding Configuration sections.
  2. With no embedding provider configured, confirm the "No embedding-capable provider" callout appears and phrase edits still save.
  3. Select a provider and model. Confirm the dimension probe runs and the remaining fields become active.
  4. Add a phrase that already exists in another tier. Confirm the cross-tier duplicate error appears before submission.
  5. Save with only phrase changes. Confirm the classifier status panel reflects the new phrase count after warmup.
  6. Confirm that collapsing and expanding the phrase lists in each tier column collapses to the same height regardless of phrase length.

Breaking changes

  • Yes
  • No

Configs with fallback: "lexical" are silently normalized to "none" on the next save. Configs with vector_store: "external" are presented and re-saved as "auto". Administrators relying on lexical fallback behavior should be aware that unclassified requests will now skip complexity tier routing rather than falling through to keyword scoring.

Related issues

Security considerations

No new auth surfaces, secrets handling, or PII exposure introduced.

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 Aug 5, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: e0f30563-8558-4c75-b834-6e3c6ef673ec

📥 Commits

Reviewing files that changed from the base of the PR and between 9ca5d04 and 87cc608.

📒 Files selected for processing (2)
  • transports/bifrost-http/lib/config_test.go
  • transports/config.schema.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • transports/bifrost-http/lib/config_test.go
  • transports/config.schema.json

📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Redesigned complexity-router settings with semantic phrase lists, embedding configuration, classifier status, validation, warnings, and save controls.
    • Added provider/model availability handling and classifier recovery after provider configuration changes.
    • Tag lists now collapse by rendered height with “Show all” and “Show less” controls.
  • Behavior Changes

    • Complexity routing now reports semantic matches or skipped results when classification is unavailable or below threshold.
    • Supported phrase storage modes are embedded and configured vector storage, with embedded fallback.
    • Lexical fallback and tier-boundary controls are no longer used.
  • Bug Fixes

    • Improved custom-scrollbar overflow handling.
    • Preserved semantic settings when resetting other complexity configuration.

Walkthrough

The change makes semantic reference phrases the only complexity-routing mechanism. It adds semantic configuration validation, classifier recovery on provider changes, a redesigned router UI, height-based tag collapsing, enabled-key propagation, and updated complexity documentation.

Changes

Semantic complexity router

Layer / File(s) Summary
Semantic configuration contract and validation
framework/configstore/..., ui/lib/types/complexityRouter.ts, ui/app/workspace/complexity-router/formSchema.ts, transports/config.schema.json, plugins/governance/complexity/config.go
Semantic reference phrases replace lexical fallback settings. Vector-store values are limited to embedded and vector_store. Validation covers durations, provider/model fields, phrase limits, duplicates, and legacy boundary defaults.
Semantic routing and classifier recovery
plugins/governance/main.go, plugins/governance/complexity/semanticclassifier.go, plugins/governance/complexity/*_test.go
Routing publishes semantic results only. Failed, timed-out, unavailable, and below-threshold classifications publish no tier and record skipped. Failed classifiers rearm for matching provider changes.
Provider state and reset wiring
transports/bifrost-http/handlers/..., transports/bifrost-http/lib/config.go, ui/lib/store/apis/providersApi.ts, ui/lib/types/governance.ts
Provider and key changes notify the semantic classifier. Provider-key enabled state flows through backend responses and UI caches. Reset operations preserve semantic settings while restoring other defaults.
Router configuration flow
ui/app/workspace/complexity-router/..., ui/app/workspace/config/views/cachingView.tsx
The router page uses semantic-only configuration. It filters providers and models by enabled keys, validates edits, polls classifier states, displays warnings, and saves through the embedding configuration sheet.
Rendered-height tag collapsing
ui/components/ui/tagInput.tsx, ui/app/globals.css
TagInput collapses tags by measured rendered height with ResizeObserver. The layout adds a fade, expansion controls, and a dedicated input row. Scroll-container overflow is explicitly hidden.
Observability and configuration documentation
core/schemas/..., framework/logstore/tables.go, ui/lib/types/logs.ts, docs/features/observability/datadog.mdx, framework/configstore/exemplars.go, plugins/governance/complexity/analyzer.go
Complexity metadata and documentation now describe semantic and skipped results, with scores defined by semantic similarity to the nearest reference phrase.

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

Mergeability Score: ⚪ Minimal · up to 87cc6

The current changes are merge-ready after normal checks and review, with no actionable merge-blocking risk remaining.

Sequence Diagram(s)

sequenceDiagram
  participant Admin
  participant ComplexityRouter
  participant EmbeddingConfigSheet
  participant SemanticClassifier
  participant GovernancePlugin

  Admin->>ComplexityRouter: Configure reference phrases and embedding settings
  ComplexityRouter->>EmbeddingConfigSheet: Validate provider and semantic fields
  EmbeddingConfigSheet-->>ComplexityRouter: Return normalized configuration
  ComplexityRouter->>SemanticClassifier: Save classifier configuration
  SemanticClassifier-->>ComplexityRouter: Report classifier state
  GovernancePlugin->>SemanticClassifier: Classify request
  SemanticClassifier-->>GovernancePlugin: Return semantic tier, score, or skipped result
Loading

Possibly related PRs

Suggested reviewers: akshaydeo, impoiler, madhuvod

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 59.52% 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 identifies the semantic router UI redesign, which is the pull request's primary user-facing change.
Description check ✅ Passed The description covers the required sections and provides relevant changes, testing steps, breaking changes, and affected areas.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch 08-05-semantic_router_ui_revamp

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.

❤️ Share

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

kohlivrinda commented Aug 5, 2026

Copy link
Copy Markdown
Member Author

@kohlivrinda
kohlivrinda marked this pull request as ready for review August 5, 2026 12:30

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ui/app/workspace/complexity-router/page.tsx (1)

301-319: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

The "Not configured" branch hides a classifier that is still serving.

isNotConfigured is derived from the live form values at line 695, not from the saved config. If a saved semantic config exists and the operator clears the provider or model in the form, this branch renders and reports "Not configured". The saved classifier keeps serving requests, and the hasUnsavedChanges notice at lines 383-387 is in the other branch, so it never appears.

Gate this branch on the saved config as well, or add the unsaved-changes notice to it.

🤖 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/app/workspace/complexity-router/page.tsx` around lines 301 - 319, Update
the semantic status rendering around the isNotConfigured/isNotSaved branch so
clearing provider or model values in the live form cannot hide the existing
saved classifier or its unsaved-changes notice. Gate the “Not configured” path
using the saved semantic configuration, or include the hasUnsavedChanges notice
in this branch, while preserving the existing status messages for genuinely
unsaved configurations.
🧹 Nitpick comments (3)
ui/lib/types/complexityRouter.ts (1)

84-102: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Reuse TIER_PHRASE_LIST_DEFINITIONS for the validation labels.

TIER_PHRASE_LIST_DEFINITIONS now holds the canonical key and label for each tier. ui/app/workspace/complexity-router/page.tsx lines 131-135 declares a second lists array with the same keys and labels for the duplicate-phrase check. If a label changes here, the validation message keeps the old wording.

Derive the validation list from this constant instead.

♻️ Proposed change in ui/app/workspace/complexity-router/page.tsx
-		const lists: Array<{ key: KeywordListKey; label: string }> = [
-			{ key: "simple_keywords", label: "Simple" },
-			{ key: "medium_keywords", label: "Medium" },
-			{ key: "complex_keywords", label: "Complex" },
-		];
+		const lists = TIER_PHRASE_LIST_DEFINITIONS;
🤖 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/types/complexityRouter.ts` around lines 84 - 102, Update the
duplicate-phrase validation in the complexity-router page to derive its lists
array from TIER_PHRASE_LIST_DEFINITIONS instead of redeclaring tier keys and
labels. Reuse each definition’s canonical key and label so validation messages
stay synchronized with the shared constant.
ui/app/workspace/complexity-router/page.tsx (2)

533-540: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Omitting semantic deletes the saved classifier configuration.

The endpoint replaces the whole record, so a payload without semantic clears the stored embedding configuration. Today the superRefine check at lines 111-127 blocks the half-filled case, and only a fully blank provider and model reaches onValid. The protection is therefore indirect: it lives in a validation rule, not at the point where the destructive payload is built.

Make the intent explicit at this site, so a later change to superRefine cannot silently enable configuration loss.

♻️ Proposed change
+		const hasProvider = values.semantic.provider.trim() !== "";
+		const hasModel = values.semantic.embedding_model.trim() !== "";
+		// A half-filled classifier must never reach here: it would drop the whole
+		// semantic block and delete the saved configuration.
+		if (hasProvider !== hasModel) return;
 		const payload: AnalyzerConfig = {
 			tier_boundaries: values.tier_boundaries,
 			keywords: values.keywords,
-			...(values.semantic.provider && values.semantic.embedding_model ? { semantic: values.semantic } : {}),
+			...(hasProvider && hasModel ? { semantic: values.semantic } : {}),
 		};
🤖 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/app/workspace/complexity-router/page.tsx` around lines 533 - 540, Update
the payload construction in the form submit handler around AnalyzerConfig so an
unconfigured semantic classifier does not omit semantic and clear the saved
configuration; preserve or explicitly handle the existing stored semantic
settings when provider and embedding_model are blank, while retaining the
current fully configured semantic behavior. Make this protection local to
payload creation rather than relying on the values.semantic superRefine
validation.

650-653: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Remove the redundant rules.validate from the phrase Controller.

useForm uses zodResolver, and the Zod schema already enforces this constraint with the same messages. Keep validation in the schema as the single source of truth.

🤖 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/app/workspace/complexity-router/page.tsx` around lines 650 - 653, Remove
the redundant rules.validate configuration from the phrase Controller using the
keywords.${key} field name. Rely exclusively on the existing useForm zodResolver
schema for non-empty phrase validation and its messages, leaving the
Controller’s control and name configuration unchanged.
🤖 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 233-244: Update InfoTip in page.tsx so its guidance is reachable
on touch devices, since TooltipTrigger/TooltipContent only works on hover/focus
and not a plain tap. Use the InfoTip symbol as the entry point and switch to a
touch-friendly pattern such as rendering the same content in a Popover on touch
pointers or showing a short inline description near the affected fields. Keep
the desktop hover/focus tooltip behavior unchanged for non-touch users and
preserve the existing help text content.
- Around line 915-919: Update the timeout field’s onChange handler to preserve
the raw input string, including "0", in field.onChange instead of passing it
through formatSemanticTimeout; continue handling an empty value as empty and
leave display parsing unchanged. Let schema validation reject non-positive
values.
- Around line 62-67: Update the supportsEmbedding check so custom providers
without allowed_requests are treated as unrestricted instead of blocked; in the
workspace router logic, change the custom_provider_config path to accept
embedding when allowed_requests is missing or when allowed_requests.embedding is
true, while preserving the existing provider.name fallback for non-custom
providers. Apply the same unrestricted-missing rule in cachingView.tsx so both
embeddingProviders selection and the no-provider warning stay consistent across
the two locations.

In `@ui/components/ui/tagInput.tsx`:
- Around line 138-145: Update the toggle button in tagInput.tsx’s expanding
control so it exposes its current state with aria-expanded. Use the existing
isCollapsed / setTagsExpanded logic around the expandButtonTestId button, and
bind the attribute to reflect whether the tag area is expanded or collapsed
without changing the click behavior or label text.

---

Outside diff comments:
In `@ui/app/workspace/complexity-router/page.tsx`:
- Around line 301-319: Update the semantic status rendering around the
isNotConfigured/isNotSaved branch so clearing provider or model values in the
live form cannot hide the existing saved classifier or its unsaved-changes
notice. Gate the “Not configured” path using the saved semantic configuration,
or include the hasUnsavedChanges notice in this branch, while preserving the
existing status messages for genuinely unsaved configurations.

---

Nitpick comments:
In `@ui/app/workspace/complexity-router/page.tsx`:
- Around line 533-540: Update the payload construction in the form submit
handler around AnalyzerConfig so an unconfigured semantic classifier does not
omit semantic and clear the saved configuration; preserve or explicitly handle
the existing stored semantic settings when provider and embedding_model are
blank, while retaining the current fully configured semantic behavior. Make this
protection local to payload creation rather than relying on the values.semantic
superRefine validation.
- Around line 650-653: Remove the redundant rules.validate configuration from
the phrase Controller using the keywords.${key} field name. Rely exclusively on
the existing useForm zodResolver schema for non-empty phrase validation and its
messages, leaving the Controller’s control and name configuration unchanged.

In `@ui/lib/types/complexityRouter.ts`:
- Around line 84-102: Update the duplicate-phrase validation in the
complexity-router page to derive its lists array from
TIER_PHRASE_LIST_DEFINITIONS instead of redeclaring tier keys and labels. Reuse
each definition’s canonical key and label so validation messages stay
synchronized with the shared constant.
🪄 Autofix

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: b1fb28f4-e837-4b03-bc1f-5c61d16927a3

📥 Commits

Reviewing files that changed from the base of the PR and between bcda613 and a322e41.

📒 Files selected for processing (6)
  • plugins/governance/complexity/config.go
  • plugins/governance/complexity/exemplars_test.go
  • ui/app/globals.css
  • ui/app/workspace/complexity-router/page.tsx
  • ui/components/ui/tagInput.tsx
  • ui/lib/types/complexityRouter.ts

Comment thread ui/app/workspace/complexity-router/page.tsx
Comment thread ui/app/workspace/complexity-router/page.tsx Outdated
Comment thread ui/app/workspace/complexity-router/page.tsx Outdated
Comment thread ui/components/ui/tagInput.tsx
@kohlivrinda
kohlivrinda force-pushed the 08-05-semantic_router_ui_revamp branch from a322e41 to 2c0c800 Compare August 5, 2026 14:47
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@kohlivrinda
kohlivrinda force-pushed the 08-05-semantic_router_ui_revamp branch from 2c0c800 to 9482b61 Compare August 5, 2026 18:46
@coderabbitai

coderabbitai Bot commented Aug 5, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@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: 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 `@plugins/governance/complexity/config.go`:
- Around line 154-163: Update the merge loop using key and combined so valid
entries append the trimmed phrase rather than the original phrase, while
continuing to skip blank values and case-insensitive duplicates. Add table cases
covering whitespace trimming, blank values, and duplicate values that differ
only by case.
🪄 Autofix

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: 19f1a04c-3306-4a7f-94a3-97410a90919f

📥 Commits

Reviewing files that changed from the base of the PR and between bcda613 and 9482b61.

📒 Files selected for processing (7)
  • plugins/governance/complexity/config.go
  • plugins/governance/complexity/exemplars_test.go
  • ui/app/globals.css
  • ui/app/workspace/complexity-router/page.tsx
  • ui/app/workspace/config/views/cachingView.tsx
  • ui/components/ui/tagInput.tsx
  • ui/lib/types/complexityRouter.ts
🚧 Files skipped from review as they are similar to previous changes (6)
  • plugins/governance/complexity/exemplars_test.go
  • ui/app/globals.css
  • ui/components/ui/tagInput.tsx
  • ui/app/workspace/config/views/cachingView.tsx
  • ui/lib/types/complexityRouter.ts
  • ui/app/workspace/complexity-router/page.tsx

Comment thread plugins/governance/complexity/config.go
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Note

GitHub couldn't provide a complete incremental comparison for this pull request, so CodeRabbit is performing a full review instead. This review may take a little longer.

@Madhuvod
Madhuvod force-pushed the 08-05-semantic_router_ui_revamp branch from f3efdc9 to 99e7268 Compare August 11, 2026 19:10
@Madhuvod
Madhuvod force-pushed the 08-04-configstore_adds_default_exemplers_in_existing_complexity_config_tiers branch from 1acbdbd to 7824de2 Compare August 11, 2026 19:10
@kohlivrinda
kohlivrinda force-pushed the 08-04-configstore_adds_default_exemplers_in_existing_complexity_config_tiers branch from 7824de2 to b9be59c Compare August 12, 2026 09:55
@kohlivrinda
kohlivrinda force-pushed the 08-05-semantic_router_ui_revamp branch 2 times, most recently from b50f5ad to f376470 Compare August 12, 2026 11:31

@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/app/workspace/complexity-router/formSchema.ts`:
- Line 60: Update ui/app/workspace/complexity-router/formSchema.ts at lines
60-60 and 179-179: in the schema enum, replace the obsolete "vector_store" value
with "auto"; in toFormValues, normalize persisted "external" to "auto" before
returning the form values so legacy configurations validate and save correctly.
- Around line 27-28: Update normalizeSessionTtl so its fallback no longer
references the undefined DEFAULT_SESSION_CONFIG identifier; use the module’s
existing in-scope session TTL default, or import the owning constant if that is
the established source.
🪄 Autofix

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: 99596557-6bfc-4b28-a1cd-9f550a0b8f67

📥 Commits

Reviewing files that changed from the base of the PR and between b50f5ad and f376470.

📒 Files selected for processing (2)
  • ui/app/workspace/complexity-router/formSchema.ts
  • ui/app/workspace/complexity-router/page.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
  • ui/app/workspace/complexity-router/page.tsx

Comment thread ui/app/workspace/complexity-router/formSchema.ts Outdated
Comment thread ui/app/workspace/complexity-router/formSchema.ts
@kohlivrinda
kohlivrinda force-pushed the 08-04-configstore_adds_default_exemplers_in_existing_complexity_config_tiers branch from b9be59c to 32f18de Compare August 12, 2026 15:04
@kohlivrinda
kohlivrinda force-pushed the 08-05-semantic_router_ui_revamp branch from f376470 to 13287ed Compare August 12, 2026 15:04

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugins/governance/complexity/semanticclassifier.go (1)

270-285: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Use a prior turn when the current turn is blank.

Line 270 reserves one slot for LastUserText before Line 283 determines that it is blank. With messageHistoryCount == 3, three nonblank prior turns and a blank current turn produce only two embedded turns. Compute the prior capacity after checking the current turn, so the function returns up to the configured count of nonblank user turns. Add a regression test for this case.

Proposed fix
-	if priorCount := messageHistoryCount - 1; priorCount > 0 && len(input.PriorUserTexts) > 0 {
+	hasLastUserText := strings.TrimSpace(input.LastUserText) != ""
+	priorCount := messageHistoryCount
+	if hasLastUserText {
+		priorCount--
+	}
+	if priorCount > 0 && len(input.PriorUserTexts) > 0 {
 		// Walk backwards so blank turns are skipped before the window is counted:
 		// slicing first would let blanks eat into the requested history count.
 		prior := make([]string, 0, priorCount)
@@
-	if strings.TrimSpace(input.LastUserText) != "" {
+	if hasLastUserText {
 		texts = append(texts, input.LastUserText)
 	}
🤖 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 `@plugins/governance/complexity/semanticclassifier.go` around lines 270 - 285,
The history assembly around LastUserText currently reserves a slot even when the
current turn is blank, reducing the number of prior turns included. Determine
whether LastUserText is nonblank before calculating priorCount, reserve capacity
only when it will be appended, and collect up to messageHistoryCount total
nonblank user turns. Add a regression test covering three nonblank prior turns
with messageHistoryCount equal to 3 and a blank current turn.
🤖 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.

Outside diff comments:
In `@plugins/governance/complexity/semanticclassifier.go`:
- Around line 270-285: The history assembly around LastUserText currently
reserves a slot even when the current turn is blank, reducing the number of
prior turns included. Determine whether LastUserText is nonblank before
calculating priorCount, reserve capacity only when it will be appended, and
collect up to messageHistoryCount total nonblank user turns. Add a regression
test covering three nonblank prior turns with messageHistoryCount equal to 3 and
a blank current turn.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 1367efc3-6167-4623-b5f2-dfe6070701d8

📥 Commits

Reviewing files that changed from the base of the PR and between f376470 and 13287ed.

📒 Files selected for processing (5)
  • core/schemas/bifrost.go
  • plugins/governance/complexity/semanticclassifier.go
  • plugins/governance/complexity/semanticclassifier_test.go
  • transports/config.schema.json
  • ui/app/workspace/complexity-router/formSchema.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • transports/config.schema.json

@Madhuvod
Madhuvod force-pushed the 08-04-configstore_adds_default_exemplers_in_existing_complexity_config_tiers branch from 32f18de to 9c6b1dc Compare August 12, 2026 19:25
@Madhuvod
Madhuvod force-pushed the 08-05-semantic_router_ui_revamp branch 2 times, most recently from 0d95748 to 9ca5d04 Compare August 12, 2026 21:16
@Madhuvod
Madhuvod force-pushed the 08-04-configstore_adds_default_exemplers_in_existing_complexity_config_tiers branch from 9c6b1dc to 95eba34 Compare August 12, 2026 21:16

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
framework/configstore/complexityconfig.go (2)

497-506: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Normalize phrases identically in the UI form.

The backend treats "shared phrase" and "shared phrase" as the same phrase. The supplied ui/app/workspace/complexity-router/formSchema.ts only trims whitespace. That input passes client validation, then fails with an opaque API error.

Use the same whitespace-collapse rule in the form validation. Add a cross-tier duplicate test with internal whitespace.

🤖 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 `@framework/configstore/complexityconfig.go` around lines 497 - 506, Update the
phrase normalization used by the UI form schema in the complexity router so
validation lowercases phrases and collapses internal whitespace with the same
strings.Fields-style rule as the backend, rather than only trimming edges. Add a
cross-tier validation test covering equivalent phrases with different internal
spacing, ensuring the duplicate is rejected client-side.

248-263: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Serialize semantic timeouts as millisecond numbers.

ComplexitySemanticConfig.MarshalJSON emits "timeout":"250ms". Emit 250 instead. Keep string decoding for backward compatibility.

Update the full stack:

  • ui/lib/types/complexityRouter.ts: accept numeric timeouts and handle them before calling .trim().
  • ui/app/workspace/complexity-router/formSchema.ts: normalize numeric API values or accept them in the schema. Otherwise numeric responses fail z.string() validation and the current helpers throw.
  • framework/configstore/complexityconfig_test.go: assert numeric serialization and round-trip behavior.
🤖 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 `@framework/configstore/complexityconfig.go` around lines 248 - 263, Change
ComplexitySemanticConfig.MarshalJSON in
framework/configstore/complexityconfig.go:248-263 to serialize nonzero timeouts
as millisecond numbers while preserving zero/omitted behavior and string
decoding compatibility. Update timeout handling in
ui/lib/types/complexityRouter.ts:14-17 and 146-157 to accept numeric values
before string operations, and update
ui/app/workspace/complexity-router/formSchema.ts to normalize or validate
numeric API timeouts. Extend
framework/configstore/complexityconfig_test.go:59-69 to assert numeric JSON
serialization and round-trip behavior.

Source: Coding guidelines

transports/config.schema.json (1)

1588-1599: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Bind vector_store.config to the parent vector_store.type. The current conditions evaluate config, so they do not enforce that the nested configuration matches the parent type. A chromem vector store can accept Redis settings, and a Redis vector store can accept Chromem settings. Apply the conditional dispatch at the vector_store level.

🤖 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 `@transports/config.schema.json` around lines 1588 - 1599, Update the
conditional schema dispatch around the vector_store type/config definitions so
the if/then checks the parent vector_store.type and routes vector_store.config
to the matching schema. Ensure chromem selects chromem_config and the equivalent
Redis branch selects redis_config, preventing configurations from being mixed
across vector store types.

Source: Path instructions

🤖 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.

Outside diff comments:
In `@framework/configstore/complexityconfig.go`:
- Around line 497-506: Update the phrase normalization used by the UI form
schema in the complexity router so validation lowercases phrases and collapses
internal whitespace with the same strings.Fields-style rule as the backend,
rather than only trimming edges. Add a cross-tier validation test covering
equivalent phrases with different internal spacing, ensuring the duplicate is
rejected client-side.
- Around line 248-263: Change ComplexitySemanticConfig.MarshalJSON in
framework/configstore/complexityconfig.go:248-263 to serialize nonzero timeouts
as millisecond numbers while preserving zero/omitted behavior and string
decoding compatibility. Update timeout handling in
ui/lib/types/complexityRouter.ts:14-17 and 146-157 to accept numeric values
before string operations, and update
ui/app/workspace/complexity-router/formSchema.ts to normalize or validate
numeric API timeouts. Extend
framework/configstore/complexityconfig_test.go:59-69 to assert numeric JSON
serialization and round-trip behavior.

In `@transports/config.schema.json`:
- Around line 1588-1599: Update the conditional schema dispatch around the
vector_store type/config definitions so the if/then checks the parent
vector_store.type and routes vector_store.config to the matching schema. Ensure
chromem selects chromem_config and the equivalent Redis branch selects
redis_config, preventing configurations from being mixed across vector store
types.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 171ddeb5-59e8-4bec-82c0-2f2f3481d3b1

📥 Commits

Reviewing files that changed from the base of the PR and between 0d95748 and 9ca5d04.

📒 Files selected for processing (8)
  • framework/configstore/complexityconfig.go
  • framework/configstore/complexityconfig_test.go
  • plugins/governance/complexity/config.go
  • transports/bifrost-http/handlers/governance_test.go
  • transports/config.schema.json
  • ui/app/workspace/complexity-router/formSchema.ts
  • ui/app/workspace/complexity-router/page.tsx
  • ui/lib/types/complexityRouter.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • ui/app/workspace/complexity-router/page.tsx
  • ui/app/workspace/complexity-router/formSchema.ts

@Madhuvod
Madhuvod force-pushed the 08-04-configstore_adds_default_exemplers_in_existing_complexity_config_tiers branch from 95eba34 to a0ce181 Compare August 12, 2026 22:06
@Madhuvod
Madhuvod force-pushed the 08-05-semantic_router_ui_revamp branch from 9ca5d04 to 87cc608 Compare August 12, 2026 22:06
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.

1 participant