Skip to content

custom model support in routing rules#1614

Open
akshaydeo wants to merge 1 commit intomainfrom
02-11-custom_model_support_in_routing_rules
Open

custom model support in routing rules#1614
akshaydeo wants to merge 1 commit intomainfrom
02-11-custom_model_support_in_routing_rules

Conversation

@akshaydeo
Copy link
Contributor

@akshaydeo akshaydeo commented Feb 11, 2026

Summary

Added support for custom model names in routing rules by introducing an allowCustomModels flag to the CEL Rule Builder and Model Multiselect components.

Changes

  • Added allowCustomModels prop to the CELRuleBuilder component
  • Modified the ValueEditor to pass the custom models flag to the ModelMultiselect component
  • Enhanced ModelMultiselect to support custom model names when the flag is enabled
  • Added documentation screenshots showing the custom model creation workflow

Type of change

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

Affected areas

  • Core (Go)
  • Transports (HTTP)
  • Providers/Integrations
  • Plugins
  • UI (Next.js)
  • Docs

How to test

  1. Navigate to the routing rules section
  2. Create a new rule that uses model selection
  3. Verify that custom models can be entered when allowCustomModels is true
  4. Verify that custom models cannot be entered when allowCustomModels is false
# UI
cd ui
pnpm i
pnpm dev

Screenshots/Recordings

Added screenshots showing the custom model creation workflow in the documentation.

Breaking changes

  • Yes
  • No

Related issues

Enables users to create routing rules for custom/private models that aren't in the predefined model list.

Security considerations

No security implications as this only affects UI components for model selection.

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
Copy link
Contributor

coderabbitai bot commented Feb 11, 2026

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Added configurable support for custom model input in CEL rule building. When enabled, users can now enter model values beyond the predefined list, providing greater flexibility in routing rule configuration.

Walkthrough

The pull request introduces a feature flag mechanism to enable custom models in the CEL rule builder. An allowCustomModels prop is added to CELRuleBuilder, passed through context, extracted in ValueEditor, and used to control custom value creation in ModelMultiselect.

Changes

Cohort / File(s) Summary
CEL Builder Components
ui/app/workspace/routing-rules/components/celBuilder/celRuleBuilder.tsx, ui/app/workspace/routing-rules/components/celBuilder/valueEditor.tsx
Adds allowCustomModels optional prop to CELRuleBuilder, propagates it via context to QueryBuilder, and updates ValueEditor to accept context and pass allowCustomValues to ModelMultiselect based on the flag.
UI Component
ui/components/ui/modelMultiselect.tsx
Introduces allowCustomValues prop to ModelMultiselectPropsBase; replaces static creation logic with dynamic allowCreate flag that gates AsyncMultiSelect creatable behavior and placeholder text.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 A custom model flag hops through,
Via context, tried and true,
ValueEditor grabs the gleam,
ModelMultiselect fulfills the dream!

🚥 Pre-merge checks | ✅ 2 | ❌ 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 (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'custom model support in routing rules' clearly describes the main feature being added—enabling custom model names in routing rules components.
Description check ✅ Passed The PR description covers all required template sections including summary, changes, type of change, affected areas, testing instructions, and completed checklist items.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 02-11-custom_model_support_in_routing_rules

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

Copy link
Contributor Author

This stack of pull requests is managed by Graphite. Learn more about stacking.

@akshaydeo akshaydeo marked this pull request as ready for review February 11, 2026 15:37
@github-actions
Copy link
Contributor

🧪 Test Suite Available

This PR can be tested by a repository admin.

Run tests for PR #1614

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Fix all issues with AI agents
In `@ui/app/workspace/routing-rules/components/celBuilder/valueEditor.tsx`:
- Around line 20-23: The declaration of the allowCustomModels constant inside
the ValueEditor function (const allowCustomModels = context?.allowCustomModels
?? false) is missing a trailing semicolon; add the semicolon to match file style
and avoid lint/format issues—update the line in the ValueEditor function where
allowCustomModels is declared to end with a semicolon.

In `@ui/components/ui/modelMultiselect.tsx`:
- Line 61: The current expression for allowCreate (allowCustomValues ||
!isSingleSelect) ignores the allowCustomValues prop in multi-select; change the
logic so allowCreate respects the prop (e.g., set allowCreate =
allowCustomValues) so custom-value creation is controlled by allowCustomValues
in both single- and multi-select modes; if instead multi-select should always
permit custom values, update the variable name and add a clarifying comment/doc
explaining that isSingleSelect implies different behavior (reference:
allowCreate, allowCustomValues, isSingleSelect).

Comment on lines +20 to +23
export function ValueEditor({ value, handleOnChange, operator, fieldData, type, context }: ValueEditorProps) {
// Extract allowCustomModels from context
const allowCustomModels = context?.allowCustomModels ?? false

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing semicolon on line 22.

Line 22 is missing a trailing semicolon, which is inconsistent with the rest of the file.

Proposed fix
 export function ValueEditor({ value, handleOnChange, operator, fieldData, type, context }: ValueEditorProps) {
 	// Extract allowCustomModels from context
-	const allowCustomModels = context?.allowCustomModels ?? false
+	const allowCustomModels = context?.allowCustomModels ?? false;
 
📝 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.

Suggested change
export function ValueEditor({ value, handleOnChange, operator, fieldData, type, context }: ValueEditorProps) {
// Extract allowCustomModels from context
const allowCustomModels = context?.allowCustomModels ?? false
export function ValueEditor({ value, handleOnChange, operator, fieldData, type, context }: ValueEditorProps) {
// Extract allowCustomModels from context
const allowCustomModels = context?.allowCustomModels ?? false;
🤖 Prompt for AI Agents
In `@ui/app/workspace/routing-rules/components/celBuilder/valueEditor.tsx` around
lines 20 - 23, The declaration of the allowCustomModels constant inside the
ValueEditor function (const allowCustomModels = context?.allowCustomModels ??
false) is missing a trailing semicolon; add the semicolon to match file style
and avoid lint/format issues—update the line in the ValueEditor function where
allowCustomModels is declared to end with a semicolon.

allowCustomValues = false,
} = props;
const isSingleSelect = props.isSingleSelect === true;
const allowCreate = allowCustomValues || !isSingleSelect;
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash

# First, let's find and examine the modelMultiselect.tsx file
find . -name "modelMultiselect.tsx" -type f

Repository: maximhq/bifrost

Length of output: 98


🏁 Script executed:

#!/bin/bash

# Check for PR-related files or documentation
find . -name "*.md" -o -name "*.txt" | grep -i "pr\|test\|readme" | head -20

Repository: maximhq/bifrost

Length of output: 861


🏁 Script executed:

#!/bin/bash

# Look for test files related to modelMultiselect
find . -name "*multiselect*" -o -name "*model*select*" | grep -i test

Repository: maximhq/bifrost

Length of output: 41


🏁 Script executed:

#!/bin/bash

# Read the modelMultiselect.tsx file
cat -n ./ui/components/ui/modelMultiselect.tsx | head -100

Repository: maximhq/bifrost

Length of output: 4106


🏁 Script executed:

#!/bin/bash

# Let's see more of the file, particularly around line 61
cat -n ./ui/components/ui/modelMultiselect.tsx | sed -n '50,100p'

Repository: maximhq/bifrost

Length of output: 2066


🏁 Script executed:

#!/bin/bash

# Let's get the full file size and read it in sections
wc -l ./ui/components/ui/modelMultiselect.tsx

Repository: maximhq/bifrost

Length of output: 102


🏁 Script executed:

#!/bin/bash

# Let's see where allowCreate is used in the file
grep -n "allowCreate" ./ui/components/ui/modelMultiselect.tsx

Repository: maximhq/bifrost

Length of output: 279


🏁 Script executed:

#!/bin/bash

# Now let's see the full context around where allowCreate is used (around lines 225-227)
cat -n ./ui/components/ui/modelMultiselect.tsx | sed -n '215,240p'

Repository: maximhq/bifrost

Length of output: 1266


🏁 Script executed:

#!/bin/bash

# Look for any test files or specs for this component
find . -type f \( -name "*test*" -o -name "*spec*" \) | xargs grep -l "modelMultiselect\|ModelMultiselect" 2>/dev/null | head -10

Repository: maximhq/bifrost

Length of output: 41


🏁 Script executed:

#!/bin/bash

# Check git history or PR info - look for commit messages or branch info
git log --oneline -20 -- ./ui/components/ui/modelMultiselect.tsx 2>/dev/null

Repository: maximhq/bifrost

Length of output: 105


🏁 Script executed:

#!/bin/bash

# Let's get the full commit details to understand the PR intent
git show f2631f7d --stat 2>/dev/null | head -50

Repository: maximhq/bifrost

Length of output: 3044


🏁 Script executed:

#!/bin/bash

# Check the commit message in detail
git show f2631f7d 2>/dev/null | head -100

Repository: maximhq/bifrost

Length of output: 1416


🏁 Script executed:

#!/bin/bash

# Let's search for any tests or documentation about custom model behavior
find . -type f \( -name "*.test.*" -o -name "*.spec.*" \) -exec grep -l "allowCustomValues\|custom.*model" {} \; 2>/dev/null

Repository: maximhq/bifrost

Length of output: 41


🏁 Script executed:

#!/bin/bash

# Look in docs or README for any mention of allowCustomValues or custom model behavior
grep -r "allowCustomValues\|allowCustom" . --include="*.md" --include="*.tsx" --include="*.ts" 2>/dev/null | grep -v node_modules | head -20

Repository: maximhq/bifrost

Length of output: 1090


🏁 Script executed:

#!/bin/bash

# Let's look at the valueEditor.tsx to understand how allowCustomValues is used
cat -n ./ui/app/workspace/routing-rules/components/celBuilder/valueEditor.tsx | grep -A 10 -B 10 "allowCustomValues"

Repository: maximhq/bifrost

Length of output: 1256


🏁 Script executed:

#!/bin/bash

# Let's look at the full context of valueEditor to understand the intent
cat -n ./ui/app/workspace/routing-rules/components/celBuilder/valueEditor.tsx | head -150

Repository: maximhq/bifrost

Length of output: 6202


🏁 Script executed:

#!/bin/bash

# Check the celRuleBuilder.tsx for more context on allowCustomModels intent
cat -n ./ui/app/workspace/routing-rules/components/celBuilder/celRuleBuilder.tsx | grep -A 5 -B 5 "allowCustomModels"

Repository: maximhq/bifrost

Length of output: 1280


🏁 Script executed:

#!/bin/bash

# Let's search for any comments or documentation that explain why allowCreate uses OR logic
grep -B 5 -A 5 "allowCreate" ./ui/components/ui/modelMultiselect.tsx

Repository: maximhq/bifrost

Length of output: 1080


🏁 Script executed:

#!/bin/bash

# Look for PR tests or documentation about the allowCustomModels behavior
find . -type f \( -name "*.md" -o -name "*.test.*" -o -name "*.spec.*" \) -exec grep -l "allowCustomModels\|allowCustomValues" {} \; 2>/dev/null

Repository: maximhq/bifrost

Length of output: 41


🏁 Script executed:

#!/antml/bin/bash

# Check if there are any comments in the git commit that explain the logic
git show f2631f7d --pretty=format:"%B" 2>/dev/null | head -100

Repository: maximhq/bifrost

Length of output: 1388


🏁 Script executed:

#!/bin/bash

# Let's check the entire modelMultiselect.tsx for any comments explaining the design decision
cat ./ui/components/ui/modelMultiselect.tsx | grep -i "custom\|allow\|create" | head -30

Repository: maximhq/bifrost

Length of output: 490


🏁 Script executed:

#!/antml:bash

# Look for PR description files or testing instructions
find . -type f \( -name "*.md" \) -path "*/.github/*" -o -name "pr*" 2>/dev/null | head -20

Repository: maximhq/bifrost

Length of output: 830


🏁 Script executed:

#!/antml/bin/bash

# Check if there's a pull_request_template that mentions testing instructions
cat ./.github/pull_request_template.md 2>/dev/null | head -100

Repository: maximhq/bifrost

Length of output: 1399


🏁 Script executed:

#!/antml/bin/bash

# Search for any test files that mention allowCustomModels or allowCustomValues
find . -type f \( -name "*.test.ts" -o -name "*.test.tsx" -o -name "*.spec.ts" -o -name "*.spec.tsx" \) 2>/dev/null | xargs grep -l "allowCustom" 2>/dev/null

Repository: maximhq/bifrost

Length of output: 43


🏁 Script executed:

#!/antml/bin/bash

# Check if there are any design decisions or comments explaining multi-select vs single-select behavior
git log --all --oneline --grep="custom.*model\|allowCustom" 2>/dev/null | head -10

Repository: maximhq/bifrost

Length of output: 945


🏁 Script executed:

#!/antml/bin/bash

# Let's check what AsyncMultiSelect does with the isCreatable prop to understand the impact
grep -n "isCreatable\|dynamicOptionCreation" ./ui/components/ui/asyncMultiselect.tsx | head -20

Repository: maximhq/bifrost

Length of output: 493


🏁 Script executed:

#!/antml/bin/bash

# Check if there are any comments in AsyncMultiSelect explaining creatable behavior
cat ./ui/components/ui/asyncMultiselect.tsx | grep -A 5 -B 5 "creatable\|create" | head -50

Repository: maximhq/bifrost

Length of output: 1673


🏁 Script executed:

#!/antml/bin/bash

# Let's check the full PR to understand if multi-select always allowing custom values was intentional
git show f2631f7d --stat 2>/dev/null | grep -i "model\|multiselect\|custom" | head -30

Repository: maximhq/bifrost

Length of output: 2094


🏁 Script executed:

#!/antml/bin/bash

# Check if there are any other usages of ModelMultiselect component that might clarify intent
grep -r "ModelMultiselect" . --include="*.tsx" --include="*.ts" | grep -v node_modules | grep -v ".git" | head -20

Repository: maximhq/bifrost

Length of output: 2083


🏁 Script executed:

#!/antml/bin/bash

# Check the git diff for modelMultiselect.tsx specifically to see what was changed in this commit
git show f2631f7d -- ./ui/components/ui/modelMultiselect.tsx 2>/dev/null | head -150

Repository: maximhq/bifrost

Length of output: 4916


🏁 Script executed:

#!/antml/bin/bash

# Let's check other usages of ModelMultiselect to see if they pass allowCustomValues in multi-select mode
grep -B 5 -A 5 "ModelMultiselect" ./ui/app/workspace/model-limits/views/modelLimitSheet.tsx 2>/dev/null | head -30

Repository: maximhq/bifrost

Length of output: 1151


🏁 Script executed:

#!/antml/bin/bash

# Check the other usages to understand if allowCustomValues is ever expected to control multi-select behavior
grep -B 5 -A 5 "ModelMultiselect" ./ui/app/workspace/providers/fragments/apiKeysFormFragment.tsx 2>/dev/null | head -30

Repository: maximhq/bifrost

Length of output: 1036


🏁 Script executed:

#!/antml/bin/bash

# Check routingRuleSheet to see how it's used without the allowCustomModels context
grep -B 10 -A 10 "ModelMultiselect" ./ui/app/workspace/routing-rules/views/routingRuleSheet.tsx 2>/dev/null | head -50

Repository: maximhq/bifrost

Length of output: 1792


🏁 Script executed:

#!/antml/bin/bash

# Let's verify what the current behavior actually is by checking if there are any existing tests
find . -type f \( -name "*.test.tsx" -o -name "*.test.ts" \) -path "*/ui/*" 2>/dev/null | head -10

Repository: maximhq/bifrost

Length of output: 41


🏁 Script executed:

#!/antml/bin/bash

# Check if there's documentation about why multi-select should always allow custom values
grep -r "multi.*select.*custom\|custom.*multi.*select" . --include="*.md" --include="*.tsx" 2>/dev/null | grep -v node_modules | head -10

Repository: maximhq/bifrost

Length of output: 174


allowCustomValues is ignored in multi-select mode.

The condition allowCustomValues || !isSingleSelect always permits custom values in multi-select mode, overriding the allowCustomValues setting. This breaks the prop's semantic contract and creates inconsistent behavior between single and multi-select modes.

If allowCustomValues is meant to control custom model creation in both modes, change line 61 to:

-	const allowCreate = allowCustomValues || !isSingleSelect;
+	const allowCreate = allowCustomValues;

If multi-select should always allow custom values regardless of the flag, the prop naming and documentation need clarification, and this design decision should be documented in comments.

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

Suggested change
const allowCreate = allowCustomValues || !isSingleSelect;
const allowCreate = allowCustomValues;
🤖 Prompt for AI Agents
In `@ui/components/ui/modelMultiselect.tsx` at line 61, The current expression for
allowCreate (allowCustomValues || !isSingleSelect) ignores the allowCustomValues
prop in multi-select; change the logic so allowCreate respects the prop (e.g.,
set allowCreate = allowCustomValues) so custom-value creation is controlled by
allowCustomValues in both single- and multi-select modes; if instead
multi-select should always permit custom values, update the variable name and
add a clarifying comment/doc explaining that isSingleSelect implies different
behavior (reference: allowCreate, allowCustomValues, isSingleSelect).

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