|
| 1 | +## ADDED Requirements |
| 2 | + |
| 3 | +### Requirement: Console navigation menu |
| 4 | +The plugin SHALL register a Console route under the system menu group for managing AI providers and models. |
| 5 | + |
| 6 | +#### Scenario: Menu registration |
| 7 | +- **WHEN** an admin user opens the Halo Console |
| 8 | +- **THEN** there SHALL be a menu item named "AI 模型配置" under the system group |
| 9 | +- **AND** clicking it SHALL navigate to the provider and model management page |
| 10 | + |
| 11 | +### Requirement: Provider list view |
| 12 | +The Console UI SHALL display a list of all `AiProvider` Extensions with their type, display name, and status. |
| 13 | + |
| 14 | +#### Scenario: View all providers |
| 15 | +- **WHEN** an admin opens the AI model configuration page |
| 16 | +- **THEN** the system SHALL display all `AiProvider` resources in a card or table layout |
| 17 | +- **AND** each item SHALL show `providerType`, `displayName`, `enabled` status, and `status.phase` |
| 18 | + |
| 19 | +### Requirement: Provider workspace layout |
| 20 | +The Console UI SHALL use a provider-centric master-detail workspace. |
| 21 | + |
| 22 | +#### Scenario: Aggregated provider workspace |
| 23 | +- **WHEN** an admin opens the AI model configuration page |
| 24 | +- **THEN** the left side SHALL display the provider list |
| 25 | +- **AND** selecting a provider SHALL open a right-side detail workspace for that provider |
| 26 | +- **AND** the workspace SHALL include both provider configuration and the models belonging to that provider |
| 27 | + |
| 28 | +### Requirement: Create new provider |
| 29 | +The Console UI SHALL allow admins to create a new `AiProvider` Extension by selecting a provider type and filling in configuration fields. |
| 30 | + |
| 31 | +#### Scenario: Create OpenAI provider |
| 32 | +- **WHEN** an admin clicks "添加模型供应商" |
| 33 | +- **AND** selects "OpenAI" as the provider type |
| 34 | +- **AND** enters display name "OpenAI Official" and binds a Halo Secret containing the API key |
| 35 | +- **AND** clicks save |
| 36 | +- **THEN** the system SHALL create a new `AiProvider` Extension via POST to the Extension API |
| 37 | +- **AND** the new provider SHALL appear in the list |
| 38 | + |
| 39 | +#### Scenario: Create AiHubMix provider without manual base URL |
| 40 | +- **WHEN** an admin clicks "添加模型供应商" |
| 41 | +- **AND** selects "AiHubMix" as the provider type |
| 42 | +- **AND** binds a Halo Secret containing the API key |
| 43 | +- **AND** clicks save |
| 44 | +- **THEN** the system SHALL create a new `AiProvider` Extension using the built-in AiHubMix preset |
| 45 | +- **AND** the admin SHALL NOT be required to manually enter AiHubMix's API base URL |
| 46 | + |
| 47 | +### Requirement: Edit provider configuration |
| 48 | +The Console UI SHALL allow admins to edit an existing `AiProvider`'s configuration. |
| 49 | + |
| 50 | +#### Scenario: Update API key |
| 51 | +- **WHEN** an admin clicks edit on an existing OpenAI provider |
| 52 | +- **AND** changes the bound Halo Secret or replaces its referenced key |
| 53 | +- **AND** clicks save |
| 54 | +- **THEN** the system SHALL update the `AiProvider` Extension via PUT to the Extension API |
| 55 | +- **AND** subsequent AI calls SHALL use the new API key |
| 56 | + |
| 57 | +#### Scenario: Edit structured provider connection fields |
| 58 | +- **WHEN** an admin edits a provider |
| 59 | +- **THEN** the form SHALL expose structured fields such as `baseUrl`, `apiKeySecretName`, and `enabled` |
| 60 | +- **AND** advanced provider-specific fields MAY be edited through an additional advanced settings area backed by `spec.config` |
| 61 | + |
| 62 | +#### Scenario: Built-in preset hides custom base URL |
| 63 | +- **WHEN** an admin edits a built-in provider such as `aihubmix` or `siliconflow` |
| 64 | +- **THEN** the form SHOULD prioritize the preset experience of editing API key and basic metadata |
| 65 | +- **AND** the admin SHALL NOT be required to fill a custom `baseUrl` |
| 66 | +- **AND** only the `openailike` provider type SHALL require manual `baseUrl` input |
| 67 | + |
| 68 | +### Requirement: API key masking and testing |
| 69 | +The Console UI SHALL protect sensitive provider keys while still allowing connectivity verification. |
| 70 | + |
| 71 | +#### Scenario: Masked API key display |
| 72 | +- **WHEN** an admin opens a provider detail page |
| 73 | +- **THEN** the UI SHALL display the bound Halo Secret name and masked preview by default |
| 74 | +- **AND** the UI SHALL allow opening a Secret edit or replacement flow when needed |
| 75 | + |
| 76 | +### Requirement: Delete provider |
| 77 | +The Console UI SHALL allow admins to delete an `AiProvider` Extension. |
| 78 | + |
| 79 | +#### Scenario: Delete provider |
| 80 | +- **WHEN** an admin clicks delete on a provider |
| 81 | +- **AND** confirms the deletion |
| 82 | +- **THEN** the system SHALL delete the `AiProvider` Extension via DELETE to the Extension API |
| 83 | +- **AND** the provider SHALL disappear from the list |
| 84 | + |
| 85 | +#### Scenario: Block deleting provider with models |
| 86 | +- **WHEN** an admin clicks delete on a provider that still has associated `AiModel` entries |
| 87 | +- **THEN** the UI SHALL prevent deletion |
| 88 | +- **AND** explain that dependent models must be removed first |
| 89 | + |
| 90 | +### Requirement: Model list view |
| 91 | +The Console UI SHALL display provider-scoped `AiModel` entries in the selected provider workspace. |
| 92 | + |
| 93 | +#### Scenario: View all models |
| 94 | +- **WHEN** an admin selects a provider |
| 95 | +- **THEN** the system SHALL display all `AiModel` resources whose `providerName` matches the selected provider |
| 96 | +- **AND** each item SHALL show the model display name and underlying `providerResourceName/modelId` reference, where `providerResourceName = AiProvider.metadata.name` |
| 97 | +- **AND** each item SHALL show its group and capability tags when available |
| 98 | + |
| 99 | +### Requirement: Model grouping and filtering |
| 100 | +The Console UI SHALL support browsing models with group and capability context. |
| 101 | + |
| 102 | +#### Scenario: Grouped model display |
| 103 | +- **WHEN** the selected provider has models with `spec.group` |
| 104 | +- **THEN** the UI SHALL group models by that value in collapsible sections |
| 105 | + |
| 106 | +#### Scenario: Filter models by keyword or capability |
| 107 | +- **WHEN** an admin enters a search term or chooses a capability filter |
| 108 | +- **THEN** the UI SHALL narrow the displayed models within the selected provider workspace |
| 109 | +- **AND** filtering SHALL work with model ID, display name, group, and capability tags |
| 110 | + |
| 111 | +### Requirement: Add model from provider |
| 112 | +The Console UI SHALL allow admins to add a new `AiModel` inside the currently selected provider workspace. |
| 113 | + |
| 114 | +#### Scenario: Add model from provider |
| 115 | +- **WHEN** an admin clicks "添加模型" |
| 116 | +- **AND** the current workspace is for provider "OpenAI Official" |
| 117 | +- **AND** enters model ID (e.g., "gpt-4o") and display name (e.g., "GPT-4o") |
| 118 | +- **AND** clicks save |
| 119 | +- **THEN** the system SHALL create a new `AiModel` Extension via POST to the Extension API |
| 120 | +- **AND** the new model SHALL appear in the list as `(OpenAI Official / GPT-4o)` |
| 121 | + |
| 122 | +#### Scenario: Add model metadata |
| 123 | +- **WHEN** an admin creates or edits a model |
| 124 | +- **THEN** the form SHALL support editing `group`, `capabilities`, `endpointType`, and `supportedTextDelta` |
| 125 | +- **AND** these values SHALL be persisted to the `AiModel` Extension |
| 126 | + |
| 127 | +### Requirement: Browse provider models |
| 128 | +The Console UI SHALL allow browsing available models from a provider's API to simplify model addition. |
| 129 | + |
| 130 | +#### Scenario: Browse and add from provider API |
| 131 | +- **WHEN** an admin selects a provider and clicks "从供应商获取模型列表" |
| 132 | +- **THEN** the system SHALL call the model listing endpoint for that provider |
| 133 | +- **AND** display available models |
| 134 | +- **AND** allow the admin to select one or more models to add as `AiModel` entries |
| 135 | + |
| 136 | +#### Scenario: Batch add discovered models |
| 137 | +- **WHEN** an admin selects multiple discovered models from the provider API result |
| 138 | +- **THEN** the UI SHALL create multiple `AiModel` entries in one batch workflow |
| 139 | +- **AND** the admin MAY set shared defaults such as `group` or `endpointType` before confirming |
| 140 | + |
| 141 | +### Requirement: Edit model |
| 142 | +The Console UI SHALL allow admins to edit an existing `AiModel`'s metadata. |
| 143 | + |
| 144 | +#### Scenario: Update model display name |
| 145 | +- **WHEN** an admin clicks edit on a model |
| 146 | +- **AND** changes the display name |
| 147 | +- **AND** clicks save |
| 148 | +- **THEN** the system SHALL update the `AiModel` Extension via PUT to the Extension API |
| 149 | + |
| 150 | +#### Scenario: Update model capabilities |
| 151 | +- **WHEN** an admin edits a model and changes capability tags such as `vision`, `reasoning`, `function_calling`, or `embedding` |
| 152 | +- **THEN** the system SHALL update the `AiModel` Extension |
| 153 | +- **AND** the updated tags SHALL immediately affect the model list display and filtering |
| 154 | + |
| 155 | +### Requirement: Delete model |
| 156 | +The Console UI SHALL allow admins to delete an `AiModel` Extension. |
| 157 | + |
| 158 | +#### Scenario: Delete model |
| 159 | +- **WHEN** an admin clicks delete on a model |
| 160 | +- **AND** confirms the deletion |
| 161 | +- **THEN** the system SHALL delete the `AiModel` Extension via DELETE to the Extension API |
| 162 | +- **AND** the model SHALL disappear from the list |
| 163 | + |
| 164 | +### Requirement: Connectivity testing |
| 165 | +The Console UI SHALL provide a manual connectivity test button for each provider. |
| 166 | + |
| 167 | +#### Scenario: Test OpenAI connectivity |
| 168 | +- **WHEN** an admin clicks "测试连通性" on an OpenAI provider |
| 169 | +- **THEN** the system SHALL call the connectivity test endpoint |
| 170 | +- **AND** display success if the API key is valid |
| 171 | +- **AND** display an error message if the API key is invalid or the service is unreachable |
| 172 | + |
| 173 | +### Requirement: Test chat debugging |
| 174 | +The Console UI SHALL provide a test chat entry that reuses the backend `test-chat` endpoint. |
| 175 | + |
| 176 | +#### Scenario: Test chat with selected model |
| 177 | +- **WHEN** an admin selects a configured `AiModel` and enters a prompt |
| 178 | +- **THEN** the UI SHALL call the backend `test-chat` endpoint for that `providerResourceName/modelId` |
| 179 | +- **AND** display the returned content and available metadata |
| 180 | + |
| 181 | +### Requirement: RBAC permissions |
| 182 | +The plugin SHALL define role templates for viewing and managing AI providers and models. |
| 183 | + |
| 184 | +#### Scenario: Permission enforcement |
| 185 | +- **WHEN** a non-admin user tries to access the AI model configuration page |
| 186 | +- **THEN** the system SHALL deny access based on RBAC rules |
| 187 | +- **AND** the menu item SHALL be hidden if the user lacks permission |
0 commit comments