Skip to content

feat(models): auto-suggest abilities from curated catalog#353

Open
martinma51 wants to merge 1 commit into
xorbitsai:mainfrom
martinma51:feature/ability-auto-fill
Open

feat(models): auto-suggest abilities from curated catalog#353
martinma51 wants to merge 1 commit into
xorbitsai:mainfrom
martinma51:feature/ability-auto-fill

Conversation

@martinma51
Copy link
Copy Markdown
Collaborator

No description provided.

Copy link
Copy Markdown
Collaborator

@rogercloud rogercloud left a comment

Choose a reason for hiding this comment

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

Review Summary

This PR is well-designed overall — the three-tier matching logic (exactwildcard_providerprovider fallback) correctly handles the common case of third-party models exposed through OpenAI-compatible endpoints. The lazy loading with double-checked locking and frontend graceful degradation are also solid.

However, after verifying each model against official documentation and checking the frontend integration, I found 3 critical data errors in the YAML catalog, 2 functional frontend gaps, and 3 minor issues that need addressing before merge.

Issues best discussed in the review body (span unmodified code)

Major: Auto-suggest missing in non-Connect mode
applyAbilitySuggestion() is only called in the Connect Wizard (Step 3), but the dialog also supports a direct "Create/Edit Model" form mode where users manually fill in model_name. In that mode, changing model_name never triggers a catalog lookup, so the auto-fill feature is completely unavailable to users who don't go through the wizard. Please add applyAbilitySuggestion() calls to the model_name onChange/onValueChange handlers in the form-mode UI as well.

Minor: Missing unit tests for model_catalog.py
The lookup() function is the core of this feature and currently has zero test coverage. Please add tests for:

  • Exact provider + model match
  • Wildcard provider match
  • Provider fallback (*) match
  • No-match (source="none") case
  • Case-insensitive matching
  • fnmatch wildcard behavior (e.g., gpt-4o* matching gpt-4o-mini)
  • YAML reload via reload_catalog()

Comment thread src/xagent/core/model/abilities_catalog.yaml
Comment thread src/xagent/core/model/abilities_catalog.yaml
Comment thread src/xagent/core/model/abilities_catalog.yaml
Comment thread src/xagent/core/model/abilities_catalog.yaml Outdated
Comment thread frontend/src/components/pages/model-management-dialog.tsx
Comment thread src/xagent/web/schemas/model.py Outdated
@qinxuye
Copy link
Copy Markdown
Contributor

qinxuye commented May 8, 2026

pre-commit failed, you can run pre-commit install on your laptop, this will do local check before committing to repo.

Copy link
Copy Markdown
Collaborator

@rogercloud rogercloud left a comment

Choose a reason for hiding this comment

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

Re-review findings

Re-reviewed the full PR after all fix commits (aa1b5ff). The original 8 review issues are all properly resolved. Found 2 additional minor issues:

  1. Form mode missing ability suggestion hintapplyAbilitySuggestion is called and abilitySuggestion state is set in form mode (via handleEdit and model_name change handlers), but the hint text ("Pre-selected based on..." / "We don't have ability info...") is only rendered in the Connect wizard section (hunk @@ -722,6 +776,22 @@), never in form mode.
  2. Redundant YAML ruledashscope/qwen2.5-vl* at file line 162 is dead code, always shadowed by dashscope/qwen*-vl* at file line 156.

Comment thread frontend/src/components/pages/model-management-dialog.tsx
Comment thread src/xagent/core/model/abilities_catalog.yaml
Copy link
Copy Markdown
Collaborator

@rogercloud rogercloud left a comment

Choose a reason for hiding this comment

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

All previous review issues resolved. Minor fix for ability suggestion clearing on provider change pushed. LGTM.

Copy link
Copy Markdown
Contributor

@qinxuye qinxuye left a comment

Choose a reason for hiding this comment

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

Review findings:

Finding 1 (docker-compose.override.yml:1-26) [added]

[P1] Don’t commit an auto-loaded Compose override

docker-compose.override.yml is automatically merged by Docker Compose, and the README’s quick start tells users to run docker compose up -d. With this file checked in, every fresh clone/deployment now builds xagent-backend:local and xagent-frontend:local from the checkout instead of pulling the pinned release images from docker-compose.yml, which changes the default install/upgrade path and can fail or take much longer on machines that only expect to run the published images. Please move this to an explicitly named dev file such as docker-compose.dev.yml and document docker compose -f docker-compose.yml -f docker-compose.dev.yml ..., or keep the override untracked.

Finding 2 (frontend/src/app/tools/page.tsx:871-880) [added]

[P2] Keep the tool policy toggle admin-only

This button is now rendered for every user, but the backing PUT /api/tools/{tool_name}/enabled endpoint still rejects non-admins with 403. Normal users will see an enable/disable control that always fails with an admin-privileges error. Please restore the isAdmin guard around the toggle button, or otherwise hide/disable it for non-admin users.

Finding 3 (src/xagent/web/api/tools.py:229-233) [added]

[P2] Don’t filter disabled tools out of the listing path

ToolFactory.create_all_tools(tool_config) now applies get_user_tool_overrides() before /api/tools/available builds the response, so a per-user disabled tool is removed from all_tools entirely. The later override loop cannot mark that tool as enabled=false/status=disabled, which regresses the display/listing behavior and hides policy-disabled tools instead of showing their disabled state. Please keep the execution-path filtering, but use an unfiltered listing path here before applying the display status.

Comment thread docker-compose.override.yml Outdated
@martinma51 martinma51 force-pushed the feature/ability-auto-fill branch 2 times, most recently from 3b716d0 to de4ee36 Compare May 10, 2026 16:43
@qinxuye
Copy link
Copy Markdown
Contributor

qinxuye commented May 11, 2026

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces an ability auto-fill feature for the model management dialog, which suggests and pre-selects model capabilities based on a curated backend catalog. The implementation spans a new YAML-based catalog, a backend suggestion service with a three-tier resolution strategy, and frontend integration with multi-language support. Feedback points out a potential race condition in the suggestion fetching logic that could result in stale UI updates and notes a minor typo in the catalog documentation.

Comment thread frontend/src/components/pages/model-management-dialog.tsx
Comment thread src/xagent/core/model/abilities_catalog.yaml Outdated
@martinma51
Copy link
Copy Markdown
Collaborator Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a curated catalog of LLM abilities to provide auto-fill suggestions and UI hints when adding or editing models. It includes a new backend service and API endpoint to lookup model capabilities based on provider and model name patterns, along with frontend integration in the model management dialog. Feedback focuses on reducing code duplication in the React component by extracting repeated state reset and change handler logic, and improving debuggability by logging errors in the API wrapper instead of silently swallowing them.

Comment thread frontend/src/components/pages/model-management-dialog.tsx Outdated
Comment thread frontend/src/components/pages/model-management-dialog.tsx
Comment thread frontend/src/lib/models.ts Outdated
Copy link
Copy Markdown
Contributor

@qinxuye qinxuye left a comment

Choose a reason for hiding this comment

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

I found two frontend state issues in the ability auto-fill flow.

Comment thread frontend/src/components/pages/model-management-dialog.tsx Outdated
Comment thread frontend/src/components/pages/model-management-dialog.tsx
@martinma51
Copy link
Copy Markdown
Collaborator Author

/gemini review

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request implements a curated ability catalog for LLM models, enabling automatic suggestion and auto-filling of capabilities like vision and tool calling during model setup. The changes encompass a YAML-based catalog, a backend lookup service with tiered resolution, and a new API endpoint. The frontend is updated to consume these suggestions, providing UI hints and auto-filling forms while respecting manual user overrides and managing asynchronous request ordering. Review feedback recommends enhancing type safety in the frontend by reusing shared interfaces and validating API responses, and suggests optimizing backend performance by pre-partitioning catalog rules into tiers during the loading process.

Comment thread frontend/src/components/pages/model-management-dialog.tsx Outdated
Comment thread frontend/src/lib/models.ts
Comment thread src/xagent/web/services/model_catalog.py
Comment thread frontend/src/components/pages/model-management-dialog.tsx
Copy link
Copy Markdown
Contributor

@qinxuye qinxuye left a comment

Choose a reason for hiding this comment

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

Found one remaining frontend state issue in the direct form provider flow.

*/
const handleModelNameChange = (newModelName: string) => {
setFormData(prev => {
void applyAbilitySuggestion(prev.model_provider, newModelName, prev.category)
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.

[P2] Recompute suggestions when the form provider changes

This helper keeps suggestions in sync when model_name changes, but the direct form's provider selector still only updates model_provider. If a user selects OpenAI/gpt-4o and gets auto-filled abilities, then switches the provider to another LLM provider while keeping the same model name, the old OpenAI hint and abilities remain in the form. Please add the same kind of provider-change path, either resetting the suggestion/model abilities or re-running applyAbilitySuggestion(newProvider, prev.model_name, prev.category) so the submitted abilities match the current provider/model pair.

@rogercloud
Copy link
Copy Markdown
Collaborator

resolve the conflict

@martinma51 martinma51 force-pushed the feature/ability-auto-fill branch from 8a1516e to 413cfd4 Compare May 21, 2026 04:01
@martinma51
Copy link
Copy Markdown
Collaborator Author

Rebased onto current upstream/main (we were -65/+17 behind) and squashed all 17 review-iteration commits into a single coherent commit 413cfd4 — the original incremental history is preserved on the backup branch on my fork if anyone wants to diff against it.

@qinxuye — re-checked your last open feedback (P2 "Recompute suggestions when the form provider changes"). The upstream provider-Select handler we now merge with already does model_name = "" + abilities = getDefaultAbilitiesForProvider(...) on provider change, which by construction prevents the stale-OpenAI-abilities-after-switching-to-Anthropic bug you described. I also added an explicit resetAbilitySuggestionState() call right above the setFormData so the "Auto-filled from " hint chip doesn't linger across provider switches, and so any in-flight lookup from the old provider has its request counter invalidated. Subsequent model_name input retriggers handleModelNameChange -> applyAbilitySuggestion(newProvider, newName, category) against the new provider as expected.

Diff vs upstream/main: 9 files / +1352 / −9 (same content footprint as before the rebase, no functional drift). Local checks:

  • pytest tests/web/test_model_catalog.py: 66 passed
  • ruff check / ruff format --check: clean
  • npm run type-check / npm run lint: clean

PR is now MERGEABLE again. Could you give it another look?

@martinma51 martinma51 force-pushed the feature/ability-auto-fill branch 3 times, most recently from 94efb75 to 51b31d5 Compare May 21, 2026 09:12
Add a backend YAML catalog (``src/xagent/core/model/abilities_catalog.yaml``)
mapping (provider, model_name_pattern) to a curated set of abilities, plus
a backend lookup service and a ``GET /api/models/ability_suggestion``
endpoint. On the frontend, the model-management dialog now auto-fills
ability checkboxes from the catalog as the user picks/types a model, with
a hint chip showing the matched rule.

Backend
  * ``model_catalog`` service with three-tier matching: exact provider+model,
    wildcard-provider, then provider-default fallback
  * YAML covers OpenAI GPT-4o/4.1/5/5.5, Claude 3.5/4/4.5/5, Gemini 2/3,
    DeepSeek V3/R1/R2/V4, Qwen 2.5/3, plus cross-provider rules for
    \"-vl\"/\"-4v\" coding-plan model names that imply vision support
  * Lazy load with double-checked locking; structured fall-throughs so
    unknown providers degrade gracefully to category defaults

Frontend
  * ``model-management-dialog.tsx`` calls the suggestion endpoint as the
    user picks (wizard) or types (form mode) a model name and as they
    switch provider; the response auto-fills abilities only when the user
    hasn't manually touched them since this wizard run
  * Stale-response guard via monotonic request counter so out-of-order
    network responses can't overwrite a newer one
  * Manual ability edits are tracked via a ref (not closure value) so
    in-flight responses can't clobber them
  * Provider/category resets invalidate any in-flight lookup before
    clearing state to prevent old-model auto-fill bleeding into the
    reset form

Review feedback addressed (rogercloud APPROVED 5/9, qinxuye 5/13):
  * P2 \"recompute suggestions when form provider changes\" — the form
    provider Select now calls ``resetAbilitySuggestionState()`` and the
    upstream-merged ``model_name=\"\"`` reset together; subsequent
    model_name input retriggers a fresh catalog lookup
  * Frontend state race conditions (stale closure of ``userTouchedAbilities``,
    in-flight requests surviving state resets) fixed via refs + counter
@martinma51 martinma51 force-pushed the feature/ability-auto-fill branch from 51b31d5 to de8e6e4 Compare May 25, 2026 01:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants