Skip to content

Agent management - add select all/none checkbox#250

Open
jfcsantos wants to merge 7 commits intomainfrom
jsantos/provider-manager-select-all
Open

Agent management - add select all/none checkbox#250
jfcsantos wants to merge 7 commits intomainfrom
jsantos/provider-manager-select-all

Conversation

@jfcsantos
Copy link
Contributor

@jfcsantos jfcsantos commented Feb 16, 2026

Overview

Adds a "select all / select none" checkbox to the header of the Models table on the organisation Providers & Models settings page so it's easier to choose less models. Also prevents saving when zero models are selected.

Screenshot 2026-02-16 at 13 35 07 Screenshot 2026-02-16 at 13 35 17 Screenshot 2026-02-16 at 13 36 42

- Add setAllProvidersEnabled() domain function for bulk provider enable/disable
- Add SET_ALL_PROVIDERS_ENABLED action to state reducer
- Wire up select-all checkbox in ProvidersTab header
- Update Checkbox component to support indeterminate state
- Checkbox operates on filtered providers only for performance
- Tri-state: checked (all), unchecked (none), indeterminate (some)
Add checkbox to select or deselect all models at once in the Models tab.
Implement sentinel value pattern to distinguish between "all models allowed"
(empty list) and "no models allowed" (sentinel value). Add validation to
prevent saving with zero models selected.

- Add select all checkbox with indeterminate state support
- Implement MODEL_ALLOW_NONE_SENTINEL for explicit empty selection
- Disable save button and show error when no models selected
- Add sanitization layer to remove sentinel before persistence
- Add comprehensive test coverage for new selection logic
…odel lists

Change the "select all models" checkbox to operate on the currently filtered/visible models instead of all models globally. The checkbox now:
- Reflects the selection state of only the filtered models
- Allows selecting/deselecting all visible models when filters are active
- Properly merges selections when working with filtered subsets
- Maintains correct indeterminate state based on filtered results

Updated the setAllModelsAllowed function to accept targetModelIds parameter, enabling granular control over which models are affected by bulk operations. Added comprehensive test coverage for filtered subset operations.
<Checkbox
checked={allSelected}
indeterminate={selectAllIndeterminate}
disabled={!canEdit}
Copy link
Contributor

Choose a reason for hiding this comment

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

SUGGESTION: Disable “select all” when there are zero models

If totalModelCount is 0 (e.g. empty dataset or failed load that still renders), clicking this checkbox could dispatch a state change with an empty allModelIds, which is surprising UX.

Suggested change
disabled={!canEdit}
disabled={!canEdit || totalModelCount === 0}

@kiloconnect
Copy link
Contributor

kiloconnect bot commented Feb 16, 2026

Code Review Summary

Status: 1 Issue Found | Recommendation: Address before merge

Overview

Severity Count
CRITICAL 0
WARNING 1
SUGGESTION 0

Fix these issues in Kilo Cloud

Issue Details (click to expand)

WARNING

File Line Issue
src/components/organizations/providers-and-models/allowLists.domain.ts 325 Bulk deselect doesn’t account for provider wildcards (filtered "deselect all" can leave provider/* entries that still allow the model)
Other Observations (not in diff)

Issues found in unchanged code that cannot receive inline comments:

File Line Issue
Files Reviewed (8 files)

export function sanitizeModelAllowListForPersistence(
modelAllowList: ReadonlyArray<string>
): string[] {
return modelAllowList.filter(entry => entry !== MODEL_ALLOW_NONE_SENTINEL);
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: sanitizeModelAllowListForPersistence() can flip "none allowed" into "all allowed"

If modelAllowList is [MODEL_ALLOW_NONE_SENTINEL], this returns [], but elsewhere [] is treated as "all models allowed" (see computeAllowedModelIds()). If persisting "no models allowed" isn’t a supported backend state, consider making sanitizeModelAllowListForPersistence() explicitly reject the sentinel (or encoding it in a way the backend understands) rather than silently converting it.

return !targetSet.has(providerSlug);
});
}
nextModelAllowList = canonicalizeModelAllowList(nextModelAllowList);
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: MODEL_ALLOW_NONE_SENTINEL may be normalized away by canonicalizeModelAllowList()

draftModelAllowList can become [MODEL_ALLOW_NONE_SENTINEL] (e.g. via setAllModelsAllowed()). Passing that through canonicalizeModelAllowList() will call normalizeModelId() on '__none__', so sentinel checks like draftModelAllowList[0] === MODEL_ALLOW_NONE_SENTINEL and the sentinel short-circuit in computeAllowedModelIds() may stop working.

Consider preserving the sentinel inside canonicalizeModelAllowList(), or guarding canonicalization sites to skip/handle the exact-sentinel state.

return canonicalizeModelAllowList(remaining);
}

const remaining = draftModelAllowList.filter(
Copy link
Contributor

Choose a reason for hiding this comment

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

WARNING: Bulk deselect doesn’t account for provider wildcards

In setAllModelsAllowed() when nextAllowed is false, the removal logic only filters out entries that exactly match targetModelIds. If a target model is effectively allowed via a provider wildcard like "provider/*", that wildcard remains and the model may still be allowed after “deselect all” on a filtered subset.

This differs from toggleModelAllowed(), which explicitly removes provider wildcards for providers offering the model when disabling. Consider extending the bulk path to also remove relevant provider/* entries (e.g., by passing provider slugs per model / rows, or computing from openRouterProviders).

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