Skip to content

Commit f6a531f

Browse files
authored
Add ai-foundation OpenSpec docs and console change (#1)
Introduce OpenSpec changes for the new ai-foundation backend foundation and a separate ai-foundation-console UI change. Adds proposals, design, tasks, and detailed specs (ai-model-service, ai-provider-config, provider-debug-api, console-model-management) along with change metadata files. Also updates openspec/config.yaml and plugin descriptor (src/main/resources/plugin.yaml) to register the new change set and plugin metadata.
1 parent 1c1aee6 commit f6a531f

13 files changed

Lines changed: 1051 additions & 20 deletions

File tree

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-05-12
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
## 背景
2+
3+
`ai-foundation` 的 backend foundation change 将先交付 `AiProvider` / `AiModel`、服务端校验、provider 适配、模型发现、连通性测试和 `test-chat` 调试接口,但不会在同一个 change 中完成完整的 Console workspace。为了降低范围、便于评审和分阶段交付,需要将 Console UI 独立成后续 change。
4+
5+
## 变更内容
6+
7+
- 新增 `ui/` 模块,交付 Halo Console 集成页面
8+
- 基于现有 `AiProvider` / `AiModel` Extension API 与 debug endpoints 构建 provider-centric workspace
9+
- 提供 provider 管理、模型管理、Secret 绑定、模型发现、连通性测试和测试对话入口
10+
- 对内置 provider type 提供“选厂商 + 填密钥”的预设表单;仅 `openailike` 暴露自定义 `baseUrl`
11+
12+
## 能力
13+
14+
### 新增能力
15+
16+
- `console-model-management`:用于管理 AI 提供商配置和模型定义的 Vue Console UI,交互方式采用主从式 provider workspace
17+
18+
## 影响
19+
20+
- 依赖 `ai-foundation` backend foundation change 先提供 `AiProvider` / `AiModel`、模型发现、连通性测试和 `test-chat` 接口
21+
- 后续评审可将后端正确性与 UI 体验分开进行
Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
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
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
## 1. UI 模块与路由
2+
3+
- [ ] 1.1 创建 `ui/` 模块并接入当前多模块构建
4+
- [ ] 1.2 在 `ui/src/index.ts` 中于系统菜单下注册 Console 路由
5+
- [ ] 1.3 确保 UI 构建产物正确打包进插件资源
6+
7+
## 2. Provider Workspace
8+
9+
- [ ] 2.1 创建 `ProviderManager.vue` 作为主管理页面,采用“左侧 provider 列表 + 右侧 provider workspace”的布局
10+
- [ ] 2.2 创建 `ProviderList.vue`,支持 provider 搜索、状态展示和切换
11+
- [ ] 2.3 创建 `ProviderDetail.vue`,在同一页面展示 provider 配置与关联模型列表
12+
- [ ] 2.4 创建 `ProviderForm.vue` 用于创建/编辑 provider,支持 baseUrl、apiKeySecretName、enabled 和高级配置
13+
- [ ] 2.5 对内置 provider type 提供“选厂商 + 填密钥”的预设表单;仅 `openailike` 暴露必填 `baseUrl`
14+
- [ ] 2.6 实现 Halo Secret 绑定/创建流程,以及密钥脱敏展示与替换交互
15+
16+
## 3. 模型管理
17+
18+
- [ ] 3.1 创建 `ModelList.vue`,按 group 分组展示模型,并显示 capability 标签
19+
- [ ] 3.2 创建 `ModelForm.vue` 用于添加/编辑模型,支持 modelId、displayName、group、capabilities、endpointType、supportedTextDelta
20+
- [ ] 3.3 实现提供商增删改查操作,使用 `@tanstack/vue-query``axiosInstance`
21+
- [ ] 3.4 实现模型增删改查操作,使用 `@tanstack/vue-query``axiosInstance`
22+
- [ ] 3.5 实现从提供商 API 获取模型列表、筛选、批量添加和共享默认值设置
23+
- [ ] 3.6 实现模型搜索、按 capability 过滤、按 group 折叠展示
24+
- [ ] 3.7 添加表单校验(provider 结构化字段、模型唯一性、providerResourceName/modelId 必填),并与服务端校验规则保持一致
25+
- [ ] 3.8 删除 provider 前检测是否仍有关联模型,并在 UI 中阻止删除
26+
27+
## 4. 调试与权限
28+
29+
- [ ] 4.1 实现连通性测试按钮,包含加载状态、检测结果和 `lastCheckedAt` 展示
30+
- [ ] 4.2 接入 `test-chat` 调试接口,允许管理员以 `providerResourceName/modelId + prompt` 发送测试请求
31+
- [ ] 4.3 确保页面受适当的 RBAC 权限保护,并在无权限时隐藏菜单
32+
- [ ] 4.4 使用 `@halo-dev/components` 和 UnoCSS 进行 UI 样式设计
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
schema: spec-driven
2+
created: 2026-05-11

0 commit comments

Comments
 (0)