Skip to content

Conversation

@Micro66
Copy link
Collaborator

@Micro66 Micro66 commented Dec 17, 2025

Summary

  • Add support for multiple model types beyond LLM: TTS, STT, Embedding, and Rerank
  • Implement backend schema with ModelCategoryType enum and type-specific configurations
  • Add API filtering by model_category_type parameter
  • Update frontend TypeScript types and i18n translations

Test plan

  • Verify backend schema changes compile without errors
  • Test /api/models/unified endpoint with model_category_type filter
  • Verify existing LLM models default to 'llm' type (backward compatibility)
  • Test frontend API client with new modelCategoryType parameter

Summary by CodeRabbit

  • New Features

    • Support for multiple model categories (LLM, TTS, STT, Embedding, Rerank) and per-category configs; model listing can be filtered by category.
    • Test connection now accepts custom headers and supports additional providers (including Gemini) and category-aware checks.
  • UX / UI

    • Added category selector, badges, conditional per-category settings in model dialogs, lists, and selection flows; some flows default to LLM-only filtering.
  • Localization

    • Added English and Chinese strings for model categories and related settings.

✏️ Tip: You can customize this high-level summary in your review settings.

- Add ModelCategoryType enum and type-specific configs (TTSConfig, STTConfig, EmbeddingConfig, RerankConfig) in backend schema
- Extend ModelSpec with modelType and type-specific configuration fields
- Add model_category_type filter parameter to list_available_models API
- Update UnifiedModel to include modelCategoryType in response
- Add TypeScript types for model category type and configurations
- Update getUnifiedModels API to support modelCategoryType filter
- Add i18n translations for model type labels and filter options (zh-CN and en)
@coderabbitai
Copy link

coderabbitai bot commented Dec 17, 2025

Walkthrough

Introduce model category typing across backend and frontend: new ModelCategoryType enum and per-type configs, a model_category_type query/filter on unified models, propagation through model aggregation and test-connection flows, TypeScript types and API param changes, UI filters/selectors, and i18n strings.

Changes

Cohort / File(s) Summary
Backend Schema
backend/app/schemas/kind.py
Add ModelCategoryType enum (llm, tts, stt, embedding, rerank) and per-type config models (TTSConfig, STTConfig, EmbeddingConfig, RerankConfig); extend ModelSpec with modelType and optional per-type config fields.
Backend API Endpoint
backend/app/api/endpoints/adapter/models.py
Add optional model_category_type query parameter to list_unified_models, propagate it to model_aggregation_service.list_available_models, extend test_model_connection request body to include model_category_type and custom_headers, and add provider-specific connection helpers.
Backend Service
backend/app/services/model_aggregation_service.py
Thread model_category_type through UnifiedModel, CRD extraction (_extract_model_info_from_crd), public model parsing, and list_available_models; default unspecified categories to "llm", filter results by model_category_type, and include modelCategoryType in model dict outputs.
Frontend API Types & Client
frontend/src/apis/models.ts
Add ModelCategoryType union and per-type config interfaces; extend ModelCRD and UnifiedModel with model-type fields; add modelCategoryType?: ModelCategoryType parameter to getUnifiedModels and serialize as model_category_type in the query.
Frontend UI — Settings Edit
frontend/src/features/settings/components/ModelEditDialog.tsx
Add model category selector, per-category protocol mapping and state (tts/stt/embedding/rerank configs), persist modelType and per-type configs into ModelCRD.spec, validate/parse custom_headers, and wire model_category_type into test/save flows.
Frontend UI — Settings List
frontend/src/features/settings/components/ModelList.tsx
Add category filter UI and state, pass filter to getUnifiedModels, display category badges from modelCategoryType, and include model_category_type and custom_headers in testConnection calls.
Frontend UI — Other usages
frontend/src/features/settings/components/BotEdit.tsx, frontend/src/features/settings/components/wizard/steps/PreviewAdjustStep.tsx, frontend/src/features/tasks/components/ModelSelector.tsx
Update unified model fetches to include model_category_type (typically 'llm') for relevant shells/components and adjust calls to the changed getUnifiedModels signature.
Frontend Localization (en/zh-CN)
frontend/src/i18n/locales/en/common.json
frontend/src/i18n/locales/zh-CN/common.json
Add localization keys for model category labels, selection/filter UI, and per-type settings (TTS voice/speed/format, STT language/format, embedding dimensions/encoding, rerank options).

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

  • Areas to focus on:
    • model_aggregation_service.py: CRD extraction, defaulting to "llm", filtering and propagation across user/group/public paths
    • backend endpoint: new model_category_type param typing, test_connection helpers and custom_headers validation
    • UnifiedModel.to_dict backward compatibility
    • frontend API: query serialization and updated getUnifiedModels signature
    • UI components: ModelEditDialog and ModelList state/load/save of per-type configs and filter integration

Possibly related PRs

Suggested reviewers

  • qdaxb
  • feifei325

Poem

🐰 I hopped through code to give models names,
LLMs and TTS in tidy frames,
Embeddings, STT, rerank too,
Filters, configs — a carrot stew,
Hooray — categories bloom anew! 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 76.92% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The PR title accurately describes the main change: adding support for multiple model types (LLM, TTS, STT, Embedding, Rerank) with clear specification of the new capabilities.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ 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 weagent/multi-model-type-support

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 and usage tips.

Copy link

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

Caution

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

⚠️ Outside diff range comments (1)
backend/app/services/model_aggregation_service.py (1)

408-433: Fix public model config to include or properly access modelType field.

The code attempts to extract modelType from the config dict using config.get("modelType", "llm"), but modelType is actually defined as a field in ModelSpec (not in modelConfig). Since ModelAdapter.to_model_dict() extracts only spec.modelConfig and returns it as config, the modelType field is lost. This means the extraction will always return the default "llm" value.

To fix this, either:

  • Pass both modelConfig and modelType separately when building the model dict, or
  • Store modelType inside modelConfig when creating/updating public models, or
  • Access modelType from the full CRD spec instead of the config dict
🧹 Nitpick comments (3)
frontend/src/apis/models.ts (1)

144-145: Remove duplicate comment.

Line 145 duplicates the comment on line 144.

 // Model Services
-// Model Services
 export const modelApis = {
backend/app/api/endpoints/adapter/models.py (1)

86-88: Consider using the ModelCategoryType enum for parameter validation.

The model_category_type parameter accepts any string, but the backend has a ModelCategoryType enum that defines valid values. Using the enum would provide automatic validation and clearer API documentation.

+from app.schemas.kind import ModelCategoryType
+
 @router.get("/unified")
 def list_unified_models(
     shell_type: Optional[str] = Query(
         None, description="Shell type to filter compatible models (Agno, ClaudeCode)"
     ),
     include_config: bool = Query(
         False, description="Whether to include full config in response"
     ),
     scope: str = Query(
         "personal",
         description="Query scope: 'personal' (default), 'group', or 'all'",
     ),
     group_name: Optional[str] = Query(
         None, description="Group name (required when scope='group')"
     ),
-    model_category_type: Optional[str] = Query(
+    model_category_type: Optional[ModelCategoryType] = Query(
         None, description="Filter by model category type (llm, tts, stt, embedding, rerank)"
     ),

If using the enum, you'll need to convert to string when passing to the service:

model_category_type=model_category_type.value if model_category_type else None,
backend/app/schemas/kind.py (1)

34-75: Type-specific configuration models are well-defined.

The config models include appropriate validation:

  • TTSConfig.speed has ge=0.25, le=4.0 bounds
  • All fields are optional with sensible defaults
  • Descriptions provide helpful context

Consider using Literal types for fields with fixed allowed values (e.g., output_format, transcription_format, encoding_format) to enable Pydantic validation, similar to the stricter typing on the frontend.

+from typing import Any, Dict, List, Literal, Optional
+
 class TTSConfig(BaseModel):
     """TTS-specific configuration"""

     voice: Optional[str] = Field(
         None, description="Voice ID (e.g., 'alloy', 'echo' for OpenAI)"
     )
     speed: Optional[float] = Field(
         1.0, ge=0.25, le=4.0, description="Speech speed (0.25-4.0)"
     )
-    output_format: Optional[str] = Field("mp3", description="Output format (mp3, wav)")
+    output_format: Optional[Literal["mp3", "wav"]] = Field("mp3", description="Output format (mp3, wav)")
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 0d950ea and 72ce701.

📒 Files selected for processing (6)
  • backend/app/api/endpoints/adapter/models.py (4 hunks)
  • backend/app/schemas/kind.py (2 hunks)
  • backend/app/services/model_aggregation_service.py (15 hunks)
  • frontend/src/apis/models.ts (5 hunks)
  • frontend/src/i18n/locales/en/common.json (1 hunks)
  • frontend/src/i18n/locales/zh-CN/common.json (1 hunks)
🧰 Additional context used
📓 Path-based instructions (9)
**/*.{py,js,ts,tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

All code comments MUST be written in English, including inline comments, block comments, docstrings, TODO/FIXME annotations, and type hints descriptions

Files:

  • backend/app/api/endpoints/adapter/models.py
  • backend/app/schemas/kind.py
  • frontend/src/apis/models.ts
  • backend/app/services/model_aggregation_service.py
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Python code must follow PEP 8 with Black formatter (line length: 88), isort for import sorting, and type hints are required
Run Black formatter and isort on Python code before committing
Run pylint and flake8 linters on Python code
Descriptive names and docstrings for public functions/classes are required in Python; extract magic numbers to constants; max 50 lines per function (preferred)

Files:

  • backend/app/api/endpoints/adapter/models.py
  • backend/app/schemas/kind.py
  • backend/app/services/model_aggregation_service.py
backend/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

backend/**/*.py: Backend API routes must be created in app/api/ directory, with schemas in app/schemas/, and business logic in app/services/
Backend must encrypt Git tokens and API keys using AES-256-CBC encryption

Files:

  • backend/app/api/endpoints/adapter/models.py
  • backend/app/schemas/kind.py
  • backend/app/services/model_aggregation_service.py
**/*.{py,ts,tsx,js,jsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

Code in writing must distinguish between code-level terminology (Team, Bot, Ghost, Shell, Model) and UI-level terminology (智能体, 机器人 in Chinese; Agent, Bot in English)

Files:

  • backend/app/api/endpoints/adapter/models.py
  • backend/app/schemas/kind.py
  • frontend/src/apis/models.ts
  • backend/app/services/model_aggregation_service.py
**/*.{py,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

When writing code comments, use Team/Bot (CRD names) when referring to code-level resources; use 智能体/机器人 when writing Chinese UI text; use Agent/Team and Bot when writing English UI text

Files:

  • backend/app/api/endpoints/adapter/models.py
  • backend/app/schemas/kind.py
  • frontend/src/apis/models.ts
  • backend/app/services/model_aggregation_service.py
backend/app/api/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

API route naming conventions should use CRD names: use /api/teams and /api/bots instead of using other naming schemes

Files:

  • backend/app/api/endpoints/adapter/models.py
frontend/src/i18n/**/*.{ts,tsx,json}

📄 CodeRabbit inference engine (AGENTS.md)

Frontend i18n keys should use CRD names (e.g., teams.title, bots.title); i18n values in zh-CN should use UI terms (e.g., '智能体列表', '机器人')

Files:

  • frontend/src/i18n/locales/en/common.json
  • frontend/src/i18n/locales/zh-CN/common.json
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: TypeScript/React code must use TypeScript strict mode, functional components, Prettier formatter, ESLint, single quotes, and no semicolons
Use const over let, never use var in JavaScript/TypeScript code

Files:

  • frontend/src/apis/models.ts
frontend/**/*.{tsx,ts,css}

📄 CodeRabbit inference engine (AGENTS.md)

Use Tailwind CSS with the specified color system CSS variables for styling (light theme: --color-bg-base, --color-text-primary, --color-primary, etc.)

Files:

  • frontend/src/apis/models.ts
🧠 Learnings (2)
📚 Learning: 2025-12-16T11:28:47.401Z
Learnt from: CR
Repo: wecode-ai/Wegent PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-16T11:28:47.401Z
Learning: Applies to frontend/src/i18n/**/*.{ts,tsx,json} : Frontend i18n keys should use CRD names (e.g., `teams.title`, `bots.title`); i18n values in zh-CN should use UI terms (e.g., '智能体列表', '机器人')

Applied to files:

  • frontend/src/i18n/locales/en/common.json
  • frontend/src/i18n/locales/zh-CN/common.json
📚 Learning: 2025-12-16T11:28:47.401Z
Learnt from: CR
Repo: wecode-ai/Wegent PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-16T11:28:47.401Z
Learning: Applies to **/*.{py,ts,tsx,js,jsx,md} : Code in writing must distinguish between code-level terminology (Team, Bot, Ghost, Shell, Model) and UI-level terminology (智能体, 机器人 in Chinese; Agent, Bot in English)

Applied to files:

  • frontend/src/i18n/locales/zh-CN/common.json
🧬 Code graph analysis (3)
backend/app/schemas/kind.py (1)
frontend/src/apis/models.ts (5)
  • ModelCategoryType (8-8)
  • TTSConfig (11-15)
  • STTConfig (17-20)
  • EmbeddingConfig (22-25)
  • RerankConfig (27-30)
frontend/src/apis/models.ts (1)
backend/app/schemas/kind.py (5)
  • ModelCategoryType (16-31)
  • TTSConfig (35-44)
  • STTConfig (47-55)
  • EmbeddingConfig (58-66)
  • RerankConfig (69-75)
backend/app/services/model_aggregation_service.py (1)
backend/app/schemas/kind.py (2)
  • Model (166-173)
  • ModelCategoryType (16-31)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Test Frontend
  • GitHub Check: Test wegent CLI Integration
  • GitHub Check: E2E Tests (Chromium)
  • GitHub Check: API Integration Tests
🔇 Additional comments (10)
frontend/src/i18n/locales/zh-CN/common.json (1)

626-648: LGTM! Translations follow coding guidelines perfectly.

The new model category type translations adhere to the established pattern: keys use code-level identifiers while values provide clear Chinese UI terms. The translations are professional and include helpful examples in the hint texts (e.g., voice IDs, dimension values, speed ranges).

Based on learnings, this correctly applies the guideline that i18n keys should use CRD names while zh-CN values should use UI-friendly Chinese terms.

frontend/src/apis/models.ts (2)

11-30: Config interface property naming uses snake_case, which is consistent with backend API responses.

The use of output_format, transcription_format, encoding_format, etc. in snake_case matches the backend Pydantic models. This is appropriate since these interfaces represent API response data.


166-191: The API client update correctly propagates the new filter parameter.

The implementation properly:

  • Adds optional modelCategoryType parameter
  • Converts to snake_case model_category_type for the API query string
  • Maintains backward compatibility by making the parameter optional
backend/app/api/endpoints/adapter/models.py (1)

128-136: Service call correctly propagates the new parameter.

The model_category_type parameter is properly passed through to the aggregation service.

backend/app/schemas/kind.py (2)

15-31: Well-structured enum with clear documentation.

The ModelCategoryType enum is properly defined with:

  • Descriptive docstring explaining each type
  • String inheritance for JSON serialization compatibility
  • LLM as the default for backward compatibility

141-157: ModelSpec extension maintains backward compatibility.

The new fields are properly integrated:

  • modelType defaults to LLM ensuring existing models work without modification
  • All type-specific configs are optional
  • Field descriptions are clear and accurate
backend/app/services/model_aggregation_service.py (3)

65-77: UnifiedModel correctly incorporates model category type with backward-compatible default.

The implementation properly:

  • Adds model_category_type as an optional parameter
  • Defaults to "llm" for backward compatibility
  • Includes it in both to_dict() and to_full_dict() outputs

147-157: CRD model category extraction handles the enum correctly.

The code properly extracts the enum value as a string using .value for JSON serialization compatibility.


370-372: Filter logic correctly compares model category types.

The filtering uses string comparison with a sensible default fallback to "llm".

frontend/src/i18n/locales/en/common.json (1)

626-648: Comprehensive i18n keys for the new model category feature.

The localization entries are well-structured:

  • Clear labels for each model category type
  • Helpful hints for configuration fields
  • Consistent naming pattern with existing keys

As per coding guidelines, i18n keys correctly use CRD-style naming (e.g., models.model_category_type).

…ment

- Add model category type selector (LLM/TTS/STT/Embedding/Rerank) in ModelEditDialog
- Add dynamic protocol options based on selected category type
- Add type-specific configuration fields:
  - TTS: voice, speed, output format
  - STT: language, transcription format
  - Embedding: dimensions, encoding format
  - Rerank: top_n, return_documents
- Add category type filter dropdown in ModelList header
- Add category type badges to model cards with color variants
- Update form state management for category-specific configs
Copy link

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

Caution

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

⚠️ Outside diff range comments (1)
frontend/src/features/settings/components/ModelEditDialog.tsx (1)

211-217: Model ID options are LLM-specific but apply to all categories.

modelOptions derives from providerType but only handles LLM providers (openai/gemini/anthropic). For non-LLM categories (e.g., TTS with Azure, Embedding with Cohere), it falls back to ANTHROPIC_MODEL_OPTIONS, showing irrelevant Claude models.

Consider:

  1. Conditionally rendering the model selector only for LLM, or
  2. Adding category-specific model options (e.g., TTS_MODEL_OPTIONS), or
  3. Defaulting to custom-only input for non-LLM categories.
   // Determine model options based on provider
+  // Only show preset model options for LLM category
   const modelOptions =
-    providerType === 'openai'
-      ? OPENAI_MODEL_OPTIONS
-      : providerType === 'gemini'
-        ? GEMINI_MODEL_OPTIONS
-        : ANTHROPIC_MODEL_OPTIONS;
+    modelCategoryType === 'llm'
+      ? (providerType === 'openai'
+          ? OPENAI_MODEL_OPTIONS
+          : providerType === 'gemini'
+            ? GEMINI_MODEL_OPTIONS
+            : ANTHROPIC_MODEL_OPTIONS)
+      : [{ value: 'custom', label: 'Custom...' }];

Also applies to: 572-596

🧹 Nitpick comments (4)
frontend/src/features/settings/components/ModelEditDialog.tsx (3)

166-183: Consider validating type-specific config values before assignment.

The type assertions (e.g., as 'mp3' | 'wav') rely on backend data being correct. If the stored value is invalid, the assertion silently coerces it. Consider adding validation:

         // Load type-specific configs
         if (model.spec.ttsConfig) {
           setTtsVoice(model.spec.ttsConfig.voice || '');
           setTtsSpeed(model.spec.ttsConfig.speed || 1.0);
-          setTtsOutputFormat(model.spec.ttsConfig.output_format as 'mp3' | 'wav' || 'mp3');
+          const outputFormat = model.spec.ttsConfig.output_format;
+          setTtsOutputFormat(outputFormat === 'mp3' || outputFormat === 'wav' ? outputFormat : 'mp3');
         }

249-263: Non-LLM categories don't receive default base URLs.

The handler only sets default base URLs for LLM models. For TTS/STT/Embedding/Rerank providers (Azure, ElevenLabs, Cohere, Jina), users must manually enter the base URL. Consider adding provider-specific defaults for other categories, or document this in the UI hint.


473-480: Placeholders are LLM-provider-specific.

apiKeyPlaceholder and baseUrlPlaceholder only handle OpenAI, Gemini, and Anthropic. For non-LLM providers (Azure, ElevenLabs, Cohere, Jina), users see the Anthropic placeholder (sk-ant-...), which may be confusing. Consider extending placeholders for category-specific providers.

frontend/src/features/settings/components/ModelList.tsx (1)

54-61: Improve type safety of badge variant mapping.

The Record<string, ...> type allows any string key, which bypasses TypeScript's type checking. Since all ModelCategoryType values are mapped, use the specific type for stricter compile-time safety.

Apply this diff:

-const MODEL_CATEGORY_BADGE_VARIANT: Record<string, 'default' | 'success' | 'info' | 'warning' | 'secondary'> = {
+const MODEL_CATEGORY_BADGE_VARIANT: Record<ModelCategoryType, 'default' | 'success' | 'info' | 'warning' | 'secondary'> = {
   llm: 'default',
   tts: 'success',
   stt: 'info',
   embedding: 'warning',
   rerank: 'secondary',
 };
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 72ce701 and 186fac8.

📒 Files selected for processing (2)
  • frontend/src/features/settings/components/ModelEditDialog.tsx (12 hunks)
  • frontend/src/features/settings/components/ModelList.tsx (9 hunks)
🧰 Additional context used
📓 Path-based instructions (8)
**/*.{py,js,ts,tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

All code comments MUST be written in English, including inline comments, block comments, docstrings, TODO/FIXME annotations, and type hints descriptions

Files:

  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/ModelEditDialog.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: TypeScript/React code must use TypeScript strict mode, functional components, Prettier formatter, ESLint, single quotes, and no semicolons
Use const over let, never use var in JavaScript/TypeScript code

Files:

  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/ModelEditDialog.tsx
**/components/**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Component names must use PascalCase, and component files must use kebab-case naming convention

Files:

  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/ModelEditDialog.tsx
frontend/src/features/**/components/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Feature-specific components should be organized in src/features/*/components/ directory

Files:

  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/ModelEditDialog.tsx
frontend/**/*.{tsx,ts,css}

📄 CodeRabbit inference engine (AGENTS.md)

Use Tailwind CSS with the specified color system CSS variables for styling (light theme: --color-bg-base, --color-text-primary, --color-primary, etc.)

Files:

  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/ModelEditDialog.tsx
**/*.{py,ts,tsx,js,jsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

Code in writing must distinguish between code-level terminology (Team, Bot, Ghost, Shell, Model) and UI-level terminology (智能体, 机器人 in Chinese; Agent, Bot in English)

Files:

  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/ModelEditDialog.tsx
**/*.{py,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

When writing code comments, use Team/Bot (CRD names) when referring to code-level resources; use 智能体/机器人 when writing Chinese UI text; use Agent/Team and Bot when writing English UI text

Files:

  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/ModelEditDialog.tsx
frontend/src/features/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

State management in frontend should use React Context API with providers defined in src/features/ (e.g., UserContext, TaskContext, ChatStreamContext, ThemeContext)

Files:

  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/ModelEditDialog.tsx
🧠 Learnings (1)
📚 Learning: 2025-12-16T11:28:47.401Z
Learnt from: CR
Repo: wecode-ai/Wegent PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-16T11:28:47.401Z
Learning: Applies to frontend/src/components/**/*.{tsx,ts} : Use shadcn/ui components for UI elements with variants: `default`, `primary`, `secondary`, `outline`, `ghost`, `link`, `destructive` for buttons

Applied to files:

  • frontend/src/features/settings/components/ModelList.tsx
🧬 Code graph analysis (1)
frontend/src/features/settings/components/ModelList.tsx (3)
frontend/src/apis/models.ts (1)
  • ModelCategoryType (8-8)
backend/app/schemas/kind.py (1)
  • ModelCategoryType (16-31)
frontend/e2e/fixtures/data-builders.ts (1)
  • model (148-158)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: Test wegent CLI Integration
  • GitHub Check: API Integration Tests
  • GitHub Check: E2E Tests (Chromium)
🔇 Additional comments (12)
frontend/src/features/settings/components/ModelEditDialog.tsx (6)

40-79: Well-structured category-to-protocol mapping.

The MODEL_CATEGORY_OPTIONS and PROTOCOL_BY_CATEGORY constants provide a clean, type-safe mapping for category-specific protocols. Good use of optional hint for LLM providers.


392-443: Clean conditional config building.

The type-specific configs are built only when the corresponding category is selected, and spread into the CRD spec. This avoids polluting the model with empty config objects.


490-511: Category type selector correctly disables on edit.

Preventing category type changes during edit avoids data inconsistency with existing type-specific configs. Good defensive design.


682-692: TTS speed input handles edge cases well.

The parseFloat(e.target.value) || 1.0 fallback ensures invalid inputs default to 1.0. The HTML min/max attributes provide client-side validation boundaries.


758-766: Integer parsing with undefined fallback is appropriate.

Using parseInt(e.target.value) || undefined correctly handles empty/invalid inputs by setting undefined, allowing the backend to use defaults.

Also applies to: 795-803


660-663: Hard-coded section headers should use translation keys.

The section headers ("TTS Configuration", "STT Configuration", "Embedding Configuration", "Rerank Configuration") are hard-coded in English. Per the coding guidelines, UI text should use translation keys for i18n support.

-              <h4 className="text-sm font-medium text-text-secondary">TTS Configuration</h4>
+              <h4 className="text-sm font-medium text-text-secondary">{t('models.tts_configuration')}</h4>

Apply similar changes for STT, Embedding, and Rerank section headers.

Also applies to: 712-715, 749-752, 786-789

⛔ Skipped due to learnings
Learnt from: CR
Repo: wecode-ai/Wegent PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-16T11:28:47.401Z
Learning: Applies to frontend/src/i18n/**/*.{ts,tsx,json} : Frontend i18n keys should use CRD names (e.g., `teams.title`, `bots.title`); i18n values in zh-CN should use UI terms (e.g., '智能体列表', '机器人')
Learnt from: CR
Repo: wecode-ai/Wegent PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-16T11:28:47.400Z
Learning: Applies to **/*.{py,js,ts,tsx,jsx} : All code comments MUST be written in English, including inline comments, block comments, docstrings, TODO/FIXME annotations, and type hints descriptions
Learnt from: CR
Repo: wecode-ai/Wegent PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-16T11:28:47.401Z
Learning: Applies to **/*.{py,ts,tsx,js,jsx,md} : Code in writing must distinguish between code-level terminology (Team, Bot, Ghost, Shell, Model) and UI-level terminology (智能体, 机器人 in Chinese; Agent, Bot in English)
frontend/src/features/settings/components/ModelList.tsx (6)

34-41: LGTM! Clean imports.

The Select component imports follow shadcn/ui patterns, and the ModelCategoryType is properly imported from the API layer.


73-73: LGTM! Properly typed field.

The modelCategoryType field is correctly typed with ModelCategoryType from the API layer and properly documented.


99-118: LGTM! Proper state and API integration.

The category filter state is correctly typed, conditionally passed to the API only when not 'all', and properly included in the useCallback dependencies to trigger re-fetching when the filter changes.


147-147: LGTM! Good backward compatibility.

Defaulting to 'llm' ensures existing models without an explicit category type are handled correctly, aligning with the PR's backward compatibility requirement.


390-394: LGTM! Consistent category badge rendering.

The category badge is properly rendered across all three model sections (user, group, public) with:

  • Dynamic translation keys for category labels
  • Variant mapping with sensible fallback to 'default'
  • Consistent positioning as the first tag

The defensive || 'default' fallback ensures graceful handling if a new category is added without updating the variant mapping.

Also applies to: 474-478, 555-559


327-348: Header layout implemented correctly.

The flex layout properly accommodates the category filter UI. The Select component integration is correct and follows shadcn/ui patterns.

Keep the type annotation on line 335. The explicit type (value: ModelCategoryType | 'all') is required for type safety and cannot be omitted. shadcn/ui's Select.onValueChange passes string type and does not support type inference, so the annotation is essential—not redundant.

Verify translation keys are present.

All required translation keys exist in the i18n files: models.title, models.description, models.filter_by_category_type, models.all_category_types, and all models.model_category_type_* keys for each category (llm, tts, stt, embedding, rerank).

Likely an incorrect or invalid review comment.

Copy link

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

Caution

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

⚠️ Outside diff range comments (1)
backend/app/services/model_aggregation_service.py (1)

415-444: Include modelType in the public model data returned by ModelAdapter.

The code attempts to extract modelType from the config dict (line 418), but modelType is stored at spec.modelType in the CRD schema—not inside spec.modelConfig. The ModelAdapter.to_model_dict() method only returns modelConfig, so modelType information is lost. Update ModelAdapter.to_model_dict() to include modelType in the returned dictionary, or extract it from the full schema before passing to UnifiedModel.

🧹 Nitpick comments (9)
frontend/src/features/settings/components/ModelEditDialog.tsx (2)

241-251: Consider resetting baseUrl when model category changes.

When switching categories (e.g., from LLM to Embedding), the base URL from the previous category may not be applicable. Consider clearing or updating baseUrl to prevent confusion.

   const handleModelCategoryTypeChange = (value: ModelCategoryType) => {
     setModelCategoryType(value);
     // Reset provider to first available option for new category
     const protocols = PROTOCOL_BY_CATEGORY[value];
     if (protocols && protocols.length > 0) {
       setProviderType(protocols[0].value);
     }
     setModelId('');
     setCustomModelId('');
+    setBaseUrl('');
   };

703-876: Missing i18n for per-category section headers.

The section headers like "TTS Configuration", "STT Configuration", "Embedding Configuration", and "Rerank Configuration" are hardcoded in English. Per coding guidelines, UI text should use translation keys.

-              <h4 className="text-sm font-medium text-text-secondary">TTS Configuration</h4>
+              <h4 className="text-sm font-medium text-text-secondary">{t('models.tts_configuration')}</h4>

Apply similar changes to STT, Embedding, and Rerank section headers.

frontend/src/apis/models.ts (1)

146-148: Duplicate comment on line 147.

There's a duplicate // Model Services comment.

 // Model Services
-// Model Services
 export const modelApis = {
backend/app/services/model_aggregation_service.py (1)

450-456: Minor: f-string in logger.debug.

Using f-strings directly in logging calls prevents lazy evaluation. Consider using %s formatting for consistency with other logging in this file (e.g., line 164).

             if model_name in seen_names:
-                logger.debug(
-                    f"Model name '{model_name}' exists in both user and public models"
-                )
+                logger.debug(
+                    "Model name '%s' exists in both user and public models",
+                    model_name,
+                )
backend/app/api/endpoints/adapter/models.py (5)

350-352: Consider validating custom_headers values are strings.

The code ensures custom_headers is a dict but doesn't validate that values are strings. Malformed headers could cause issues downstream.

     # Ensure custom_headers is a dict
     if not isinstance(custom_headers, dict):
         custom_headers = {}
+    else:
+        # Filter out non-string values from custom_headers
+        custom_headers = {
+            k: v for k, v in custom_headers.items()
+            if isinstance(k, str) and isinstance(v, str)
+        }

373-375: Improve exception handling per static analysis hints.

Use logging.exception instead of logging.error to include traceback, and avoid f-string in logging call.

     except Exception as e:
-        logger.error(f"Model connection test failed: {str(e)}")
-        return {"success": False, "message": f"Connection failed: {str(e)}"}
+        logger.exception("Model connection test failed: %s", e)
+        return {"success": False, "message": f"Connection failed: {e!s}"}

441-446: Remove unused variable assignment.

The response variable is assigned but never used, as flagged by static analysis.

     else:
         # Default: LLM - use chat completions
-        response = client.chat.completions.create(
+        client.chat.completions.create(
             model=model_id,
             messages=[{"role": "user", "content": "hi"}],
             max_tokens=128,
         )
         return {"success": True, "message": f"Successfully connected to {model_id}"}

476-481: Remove unused variable assignment.

Same issue as above - response is assigned but never used.

-    response = client.messages.create(
+    client.messages.create(
         model=model_id,
         max_tokens=128,
         messages=[{"role": "user", "content": "hi"}],
     )
     return {"success": True, "message": f"Successfully connected to {model_id}"}

459-464: Anthropic model category validation is overly restrictive.

The condition if model_category_type not in ["llm", None, ""] will always be true when model_category_type is the string "llm" (which it defaults to on line 342), so this check works. However, the empty string check is unnecessary since the default is "llm", not "".

     # Anthropic currently only supports LLM models
-    if model_category_type not in ["llm", None, ""]:
+    if model_category_type != "llm":
         return {
             "success": False,
             "message": f"Anthropic provider does not support {model_category_type} models",
         }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 186fac8 and 4be0e9c.

📒 Files selected for processing (9)
  • backend/app/api/endpoints/adapter/models.py (6 hunks)
  • backend/app/schemas/kind.py (2 hunks)
  • backend/app/services/model_aggregation_service.py (15 hunks)
  • frontend/src/apis/models.ts (10 hunks)
  • frontend/src/features/settings/components/BotEdit.tsx (1 hunks)
  • frontend/src/features/settings/components/ModelEditDialog.tsx (13 hunks)
  • frontend/src/features/settings/components/ModelList.tsx (10 hunks)
  • frontend/src/features/settings/components/wizard/steps/PreviewAdjustStep.tsx (1 hunks)
  • frontend/src/features/tasks/components/ModelSelector.tsx (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • backend/app/schemas/kind.py
🧰 Additional context used
📓 Path-based instructions (11)
**/*.{py,js,ts,tsx,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

All code comments MUST be written in English, including inline comments, block comments, docstrings, TODO/FIXME annotations, and type hints descriptions

Files:

  • frontend/src/features/settings/components/BotEdit.tsx
  • frontend/src/features/tasks/components/ModelSelector.tsx
  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/wizard/steps/PreviewAdjustStep.tsx
  • backend/app/services/model_aggregation_service.py
  • frontend/src/apis/models.ts
  • frontend/src/features/settings/components/ModelEditDialog.tsx
  • backend/app/api/endpoints/adapter/models.py
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,tsx,js,jsx}: TypeScript/React code must use TypeScript strict mode, functional components, Prettier formatter, ESLint, single quotes, and no semicolons
Use const over let, never use var in JavaScript/TypeScript code

Files:

  • frontend/src/features/settings/components/BotEdit.tsx
  • frontend/src/features/tasks/components/ModelSelector.tsx
  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/wizard/steps/PreviewAdjustStep.tsx
  • frontend/src/apis/models.ts
  • frontend/src/features/settings/components/ModelEditDialog.tsx
**/components/**/*.{tsx,ts,jsx,js}

📄 CodeRabbit inference engine (AGENTS.md)

Component names must use PascalCase, and component files must use kebab-case naming convention

Files:

  • frontend/src/features/settings/components/BotEdit.tsx
  • frontend/src/features/tasks/components/ModelSelector.tsx
  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/wizard/steps/PreviewAdjustStep.tsx
  • frontend/src/features/settings/components/ModelEditDialog.tsx
frontend/src/features/**/components/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

Feature-specific components should be organized in src/features/*/components/ directory

Files:

  • frontend/src/features/settings/components/BotEdit.tsx
  • frontend/src/features/tasks/components/ModelSelector.tsx
  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/wizard/steps/PreviewAdjustStep.tsx
  • frontend/src/features/settings/components/ModelEditDialog.tsx
frontend/**/*.{tsx,ts,css}

📄 CodeRabbit inference engine (AGENTS.md)

Use Tailwind CSS with the specified color system CSS variables for styling (light theme: --color-bg-base, --color-text-primary, --color-primary, etc.)

Files:

  • frontend/src/features/settings/components/BotEdit.tsx
  • frontend/src/features/tasks/components/ModelSelector.tsx
  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/wizard/steps/PreviewAdjustStep.tsx
  • frontend/src/apis/models.ts
  • frontend/src/features/settings/components/ModelEditDialog.tsx
**/*.{py,ts,tsx,js,jsx,md}

📄 CodeRabbit inference engine (AGENTS.md)

Code in writing must distinguish between code-level terminology (Team, Bot, Ghost, Shell, Model) and UI-level terminology (智能体, 机器人 in Chinese; Agent, Bot in English)

Files:

  • frontend/src/features/settings/components/BotEdit.tsx
  • frontend/src/features/tasks/components/ModelSelector.tsx
  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/wizard/steps/PreviewAdjustStep.tsx
  • backend/app/services/model_aggregation_service.py
  • frontend/src/apis/models.ts
  • frontend/src/features/settings/components/ModelEditDialog.tsx
  • backend/app/api/endpoints/adapter/models.py
**/*.{py,ts,tsx,js,jsx}

📄 CodeRabbit inference engine (AGENTS.md)

When writing code comments, use Team/Bot (CRD names) when referring to code-level resources; use 智能体/机器人 when writing Chinese UI text; use Agent/Team and Bot when writing English UI text

Files:

  • frontend/src/features/settings/components/BotEdit.tsx
  • frontend/src/features/tasks/components/ModelSelector.tsx
  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/wizard/steps/PreviewAdjustStep.tsx
  • backend/app/services/model_aggregation_service.py
  • frontend/src/apis/models.ts
  • frontend/src/features/settings/components/ModelEditDialog.tsx
  • backend/app/api/endpoints/adapter/models.py
frontend/src/features/**/*.{tsx,ts}

📄 CodeRabbit inference engine (AGENTS.md)

State management in frontend should use React Context API with providers defined in src/features/ (e.g., UserContext, TaskContext, ChatStreamContext, ThemeContext)

Files:

  • frontend/src/features/settings/components/BotEdit.tsx
  • frontend/src/features/tasks/components/ModelSelector.tsx
  • frontend/src/features/settings/components/ModelList.tsx
  • frontend/src/features/settings/components/wizard/steps/PreviewAdjustStep.tsx
  • frontend/src/features/settings/components/ModelEditDialog.tsx
**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

**/*.py: Python code must follow PEP 8 with Black formatter (line length: 88), isort for import sorting, and type hints are required
Run Black formatter and isort on Python code before committing
Run pylint and flake8 linters on Python code
Descriptive names and docstrings for public functions/classes are required in Python; extract magic numbers to constants; max 50 lines per function (preferred)

Files:

  • backend/app/services/model_aggregation_service.py
  • backend/app/api/endpoints/adapter/models.py
backend/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

backend/**/*.py: Backend API routes must be created in app/api/ directory, with schemas in app/schemas/, and business logic in app/services/
Backend must encrypt Git tokens and API keys using AES-256-CBC encryption

Files:

  • backend/app/services/model_aggregation_service.py
  • backend/app/api/endpoints/adapter/models.py
backend/app/api/**/*.py

📄 CodeRabbit inference engine (AGENTS.md)

API route naming conventions should use CRD names: use /api/teams and /api/bots instead of using other naming schemes

Files:

  • backend/app/api/endpoints/adapter/models.py
🧠 Learnings (1)
📚 Learning: 2025-12-16T11:28:47.401Z
Learnt from: CR
Repo: wecode-ai/Wegent PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-16T11:28:47.401Z
Learning: Applies to frontend/src/components/**/*.{tsx,ts} : Use shadcn/ui components for UI elements with variants: `default`, `primary`, `secondary`, `outline`, `ghost`, `link`, `destructive` for buttons

Applied to files:

  • frontend/src/features/settings/components/ModelList.tsx
🧬 Code graph analysis (3)
backend/app/services/model_aggregation_service.py (1)
backend/app/schemas/kind.py (2)
  • Model (167-174)
  • ModelCategoryType (16-31)
frontend/src/apis/models.ts (3)
backend/app/schemas/kind.py (5)
  • ModelCategoryType (16-31)
  • TTSConfig (35-44)
  • STTConfig (47-55)
  • EmbeddingConfig (58-66)
  • RerankConfig (69-75)
frontend/src/apis/client.ts (1)
  • apiClient (110-110)
frontend/e2e/fixtures/data-builders.ts (1)
  • model (148-158)
frontend/src/features/settings/components/ModelEditDialog.tsx (1)
frontend/src/apis/models.ts (5)
  • ModelCategoryType (8-8)
  • TTSConfig (11-15)
  • STTConfig (17-20)
  • EmbeddingConfig (22-25)
  • RerankConfig (27-30)
🪛 Ruff (0.14.8)
backend/app/api/endpoints/adapter/models.py

373-373: Do not catch blind exception: Exception

(BLE001)


374-374: Use logging.exception instead of logging.error

Replace with exception

(TRY400)


374-374: Use explicit conversion flag

Replace with conversion flag

(RUF010)


375-375: Use explicit conversion flag

Replace with conversion flag

(RUF010)


416-419: Consider moving this statement to an else block

(TRY300)


441-441: Local variable response is assigned to but never used

Remove assignment to unused variable response

(F841)


476-476: Local variable response is assigned to but never used

Remove assignment to unused variable response

(F841)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: Test wegent CLI Integration
  • GitHub Check: Test Frontend
  • GitHub Check: API Integration Tests
  • GitHub Check: E2E Tests (Chromium)
🔇 Additional comments (23)
frontend/src/features/settings/components/BotEdit.tsx (1)

379-386: LGTM! Correctly filters models to LLM category for bot configuration.

The filter ensures only LLM models are available for bot selection, which aligns with the PR objectives.

frontend/src/features/settings/components/wizard/steps/PreviewAdjustStep.tsx (1)

266-267: LGTM! Properly filters to LLM models for chat preview.

The API call correctly passes all parameters including the new 'llm' category filter.

frontend/src/features/tasks/components/ModelSelector.tsx (1)

157-158: LGTM! Correctly filters to LLM models for chat model selection.

The change is consistent with other components and ensures only LLM models appear in the chat model selector.

frontend/src/features/settings/components/ModelList.tsx (3)

44-65: Good implementation of category filter options and badge variants.

The commented-out TTS/STT options indicate these are planned for future enablement. The badge variant mapping provides visual differentiation for different model categories.


349-372: LGTM! Clean category filter UI implementation.

The filter follows the established UI patterns and properly integrates with the model fetching logic via state.


233-252: LGTM! Test connection properly passes model category type.

This enables the backend to use the appropriate API endpoint for testing different model categories (e.g., embeddings API vs chat completions API).

frontend/src/features/settings/components/ModelEditDialog.tsx (5)

48-90: Well-structured category and protocol configuration.

The PROTOCOL_BY_CATEGORY mapping provides clear protocol options for each model category, with helpful hints for LLM protocols. TTS/STT options are appropriately commented out for future enablement.


141-158: LGTM! Per-category state variables properly initialized with sensible defaults.

The state management for TTS, STT, Embedding, and Rerank configurations follows React best practices with appropriate default values.


423-486: LGTM! Clean implementation of per-category config building.

The conditional config building ensures only the relevant category's configuration is included in the CRD spec, avoiding unnecessary data.


533-554: LGTM! Model category selector appropriately disabled during editing.

Preventing category changes for existing models is the correct approach to avoid configuration inconsistencies.


304-313: Update TestConnectionRequest type to accept all supported provider types, not just LLM providers.

The cast on line 307 masks a type safety issue: PROTOCOL_BY_CATEGORY contains providers like 'azure', 'elevenlabs', 'google', and 'custom' for TTS, STT, embedding, and rerank categories, but TestConnectionRequest.provider_type only accepts 'openai' | 'anthropic' | 'gemini'. When users select non-LLM categories and providers, the cast silently passes invalid values to the API. Update the TestConnectionRequest interface in frontend/src/apis/models.ts to include all valid providers from PROTOCOL_BY_CATEGORY, then remove the unsafe cast.

frontend/src/apis/models.ts (6)

7-8: LGTM! Type definition aligns with backend.

The ModelCategoryType union type correctly mirrors the backend ModelCategoryType enum values from app/schemas/kind.py.


10-30: Type-specific config interfaces look good.

The interfaces correctly define optional properties matching the backend Pydantic models. However, note that the output_format in TTSConfig (line 14) uses a restricted union 'mp3' | 'wav' while the backend TTSConfig accepts any string with default "mp3". Same pattern for other format fields. This is acceptable as it provides stricter typing on the frontend.


51-58: New spec fields for multi-type model support look correct.

The fields align with the backend Model schema. Consider documenting that modelType here refers to the category (llm/tts/stt/embedding/rerank), to avoid confusion with ModelTypeEnum (public/user/group) defined on line 104.


115-116: LGTM!

The modelCategoryType field correctly uses the ModelCategoryType union type and is optional for backward compatibility.


128-130: LGTM!

New fields for custom_headers and model_category_type in TestConnectionRequest match the backend API expectations.


166-190: LGTM! API parameter handling is correct.

The modelCategoryType parameter is properly serialized as model_category_type in the query string (line 189), matching the backend's snake_case convention for query parameters.

backend/app/services/model_aggregation_service.py (4)

65-81: LGTM! Constructor properly handles backward compatibility.

The model_category_type parameter defaults to None and is set to "llm" when not provided, ensuring backward compatibility with existing models.


83-104: LGTM!

The to_dict method correctly outputs modelCategoryType using camelCase for the API response, consistent with other field naming conventions in the method.


127-171: LGTM! Model info extraction handles the new field correctly.

The method properly extracts model_category_type from the CRD spec's modelType field and defaults to "llm" in all fallback scenarios for backward compatibility.


374-397: LGTM! User/group model filtering and construction.

The filtering logic correctly uses info.get("model_category_type", "llm") with a default, and passes the value through to UnifiedModel construction.

backend/app/api/endpoints/adapter/models.py (2)

86-89: LGTM! Query parameter properly documented.

The model_category_type parameter is correctly typed as Optional[str] with clear description. It follows the same pattern as other optional query parameters in this endpoint.


505-523: LGTM! Gemini embedding test implementation.

The URL construction logic correctly handles different base URL formats and the embedding endpoint is properly tested with a minimal payload.

Comment on lines +423 to +437
elif model_category_type == "stt":
# STT models require audio input, hard to test without actual audio
# Return a message indicating manual verification is needed
return {
"success": True,
"message": f"STT model {model_id} configured. Audio transcription test requires actual audio input.",
}

elif model_category_type == "rerank":
# Rerank models are typically not standard OpenAI API
# They may use custom endpoints
return {
"success": True,
"message": f"Rerank model {model_id} configured. Please verify with actual rerank request.",
}
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

STT and Rerank tests return success without actual verification.

Both STT (lines 423-429) and Rerank (lines 431-437) handlers return success: True without performing any actual connection test. This could mislead users into thinking their configuration is valid when it hasn't been tested.

Consider either:

  1. Returning a different status like "verified": false alongside the message
  2. Documenting this limitation clearly in the API response
     elif model_category_type == "stt":
         # STT models require audio input, hard to test without actual audio
-        # Return a message indicating manual verification is needed
         return {
-            "success": True,
-            "message": f"STT model {model_id} configured. Audio transcription test requires actual audio input.",
+            "success": True,
+            "message": f"STT model {model_id} configuration saved. Note: Connection was not verified - audio transcription test requires actual audio input.",
         }

     elif model_category_type == "rerank":
         # Rerank models are typically not standard OpenAI API
-        # They may use custom endpoints
         return {
-            "success": True,
-            "message": f"Rerank model {model_id} configured. Please verify with actual rerank request.",
+            "success": True,
+            "message": f"Rerank model {model_id} configuration saved. Note: Connection was not verified - please test with actual rerank request.",
         }
📝 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
elif model_category_type == "stt":
# STT models require audio input, hard to test without actual audio
# Return a message indicating manual verification is needed
return {
"success": True,
"message": f"STT model {model_id} configured. Audio transcription test requires actual audio input.",
}
elif model_category_type == "rerank":
# Rerank models are typically not standard OpenAI API
# They may use custom endpoints
return {
"success": True,
"message": f"Rerank model {model_id} configured. Please verify with actual rerank request.",
}
elif model_category_type == "stt":
# STT models require audio input, hard to test without actual audio
return {
"success": True,
"message": f"STT model {model_id} configuration saved. Note: Connection was not verified - audio transcription test requires actual audio input.",
}
elif model_category_type == "rerank":
# Rerank models are typically not standard OpenAI API
return {
"success": True,
"message": f"Rerank model {model_id} configuration saved. Note: Connection was not verified - please test with actual rerank request.",
}
🤖 Prompt for AI Agents
In backend/app/api/endpoints/adapter/models.py around lines 423 to 437, the STT
and Rerank branches return success: True without any verification; change the
response to include a verification flag and clearer documentation by returning
success: True (indicating config saved) plus "verified": False and update the
message to state that no live verification was performed and manual testing is
required (e.g., "configured but not verified; manual test required"), so callers
can distinguish configured vs actually verified endpoints.

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.

2 participants