first commit
This commit is contained in:
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-07-02
|
||||
@@ -0,0 +1,77 @@
|
||||
## Context
|
||||
|
||||
The platform already has domain, DTO, validator, repository, service, and HTTP API foundations for AI provider resources. The route catalog previously deferred provider test/model actions, and `platform_web/pages/AiProvidersPage.tsx` is still a placeholder. The architecture requires AI provider credentials and base URLs to remain platform-owned, and plugin pages must never receive raw provider keys.
|
||||
|
||||
This change turns AI provider management into a usable first-party workflow across `platform/` and `platform_web/` while keeping the scope intentionally local: configuration validation, status management, and model inventory are platform metadata operations, not live external model calls.
|
||||
|
||||
## Goals / Non-Goals
|
||||
|
||||
**Goals:**
|
||||
|
||||
- Add backend AI provider management APIs for update, enable/disable, configuration test, and model listing.
|
||||
- Keep all provider responses redacted to `apiKeyRef`; reject raw keys in create and update paths.
|
||||
- Keep management behavior inside `service.Core` and named DTOs, with handlers acting as transport adapters.
|
||||
- Implement a functional AI provider management page in `platform_web` with API client/types, create/edit form, status filters, model display, enable/disable, and test actions.
|
||||
- Add backend and frontend tests for management behavior and secret redaction.
|
||||
|
||||
**Non-Goals:**
|
||||
|
||||
- No real OpenAI/Claude/local provider network calls.
|
||||
- No secret vault implementation or raw secret storage.
|
||||
- No plugin-facing AI invocation API.
|
||||
- No AI-generated config diff/write dispatch.
|
||||
- No authentication, RBAC, SQL persistence, run-side behavior, billing, cloud host sales, or agent-provider/cloud-provider workflows.
|
||||
|
||||
## Decisions
|
||||
|
||||
### Decision 1: Provider test is metadata validation
|
||||
|
||||
The test endpoint will validate stored provider metadata and report whether the provider is active, has a secret reference when required, includes a default model in its model list, and passes existing validator rules. It will not contact external AI services.
|
||||
|
||||
Alternative considered: performing a live chat/model request. Rejected because this change must not introduce external network behavior, raw key handling, or provider-specific clients.
|
||||
|
||||
### Decision 2: Status changes use a dedicated action route
|
||||
|
||||
Enable/disable behavior will use `POST /api/v1/ai-providers/{id}/status` with a named status request DTO. General update will edit provider metadata while preserving status unless the dedicated action changes it.
|
||||
|
||||
Alternative considered: overloading generic update with status changes. Rejected because explicit status actions are easier to audit and test.
|
||||
|
||||
### Decision 3: Update uses full provider metadata
|
||||
|
||||
The update request will accept the same safe fields as create plus provider metadata fields, with no raw key field. `apiKeyRef` remains a secret reference string and is validated the same way as create.
|
||||
|
||||
Alternative considered: partial patch semantics. Rejected for this stage because full update is deterministic, simpler to validate, and matches the existing in-memory repository implementation.
|
||||
|
||||
### Decision 4: Frontend page owns UI state but not contracts
|
||||
|
||||
`AiProvidersPage` will manage local loading/form selection state, while API DTOs and client functions remain in `platform_web/api`. The page will use API responses for persisted provider data and seed a local demo fallback only when the backend is unavailable in standalone frontend development.
|
||||
|
||||
Alternative considered: hard-coded page data only. Rejected because this would not exercise the platform API client or management workflow.
|
||||
|
||||
### Decision 5: UI stays operational and dense
|
||||
|
||||
The AI provider page will use a table, compact metrics, a form panel, filter controls, and action buttons. It will avoid marketing layout and will not display instructional copy or raw secrets.
|
||||
|
||||
Alternative considered: a large hero/empty-state page. Rejected because this is an operational console area used for repeated configuration work.
|
||||
|
||||
## Risks / Trade-offs
|
||||
|
||||
- [Risk] The test endpoint can only validate metadata, not live connectivity. Mitigation: return an explicit `mode` value and reserve live tests for a later provider invocation change.
|
||||
- [Risk] Frontend fallback data could be mistaken for persisted data. Mitigation: mark fallback state as local-only in view state and prefer API data whenever the backend responds.
|
||||
- [Risk] Full update requires clients to send all editable provider fields. Mitigation: centralize the request builder in the page and API client.
|
||||
- [Risk] In-memory backend state remains process-local. Mitigation: retain service/router injection and leave persistence to a future storage change.
|
||||
|
||||
## Migration Plan
|
||||
|
||||
1. Add backend DTOs, service methods, handler routes, and route catalog updates for AI provider management.
|
||||
2. Add backend service/API tests covering update, status, test/model responses, duplicate/missing resources, and raw key rejection.
|
||||
3. Add frontend API types/client methods, replace the placeholder AI provider page, and add rendering/client tests.
|
||||
4. Run backend tests, frontend tests/build, structure check, browser walkthrough, and strict OpenSpec validation.
|
||||
|
||||
Rollback before dependent changes is removal of the new AI provider management endpoints/page and this OpenSpec change. After dependent plugin or frontend workflows consume these APIs, rollback must be handled through a new OpenSpec change.
|
||||
|
||||
## Open Questions
|
||||
|
||||
- Which persistence-backed secret reference provider should store `apiKeyRef` targets?
|
||||
- Which later change should add live provider connectivity tests and model discovery calls?
|
||||
- Which authorization policy will restrict who can create or disable providers?
|
||||
@@ -0,0 +1,28 @@
|
||||
## Why
|
||||
|
||||
AI providers are a required first-party platform area, but the backend and console currently expose only the generic core resource API and a placeholder page. Operators need a usable management workflow that configures model endpoints safely without exposing raw provider credentials to plugins or UI responses.
|
||||
|
||||
## What Changes
|
||||
|
||||
- Add AI-provider-specific backend management actions for update, enable/disable, configuration test, and configured model listing.
|
||||
- Preserve the existing create/list/detail API while tightening response behavior around secret references and raw key rejection.
|
||||
- Add service methods and DTOs for AI provider management without adding external provider calls or raw secret storage.
|
||||
- Replace the `platform_web` placeholder AI provider page with a functional management view that lists providers, creates/edits provider metadata, toggles status, tests configuration, and displays model inventory.
|
||||
- Add frontend API types/client methods and tests that assert raw keys are never part of returned provider shapes.
|
||||
|
||||
## Capabilities
|
||||
|
||||
### New Capabilities
|
||||
|
||||
- `ai-provider-management`: Safe platform and management-console workflows for creating, editing, enabling/disabling, testing, and viewing AI provider configuration.
|
||||
|
||||
### Modified Capabilities
|
||||
|
||||
- None.
|
||||
|
||||
## Impact
|
||||
|
||||
- Affects `platform/` and `platform_web/` only.
|
||||
- Extends AI provider DTOs, service methods, API handlers, route catalog, frontend API contracts, and the AI provider page.
|
||||
- Adds backend API tests, frontend rendering/client tests, and a browser walkthrough.
|
||||
- Does not add raw key exposure, plugin-facing raw credentials, run-side behavior, external AI network invocation, billing, cloud host sales, or agent-provider/cloud-provider workflows.
|
||||
+79
@@ -0,0 +1,79 @@
|
||||
## ADDED Requirements
|
||||
|
||||
### Requirement: AI providers can be managed through platform APIs
|
||||
The platform SHALL expose AI provider management APIs for create, list, detail, update, enable/disable, configuration test, and configured model listing.
|
||||
|
||||
#### Scenario: Provider is updated
|
||||
- **WHEN** a client sends a valid provider update request to an existing AI provider
|
||||
- **THEN** the platform MUST validate the request, persist the metadata through `service.Core`, and return a redacted `AIProviderResponse`
|
||||
|
||||
#### Scenario: Provider status is changed
|
||||
- **WHEN** a client enables or disables an existing AI provider through the status action route
|
||||
- **THEN** the platform MUST persist the requested status and return a redacted `AIProviderResponse`
|
||||
|
||||
#### Scenario: Provider configuration is tested
|
||||
- **WHEN** a client tests an existing AI provider
|
||||
- **THEN** the platform MUST validate stored metadata locally and return a named test result DTO without contacting external AI services
|
||||
|
||||
#### Scenario: Provider model list is requested
|
||||
- **WHEN** a client requests configured models for an existing AI provider
|
||||
- **THEN** the platform MUST return the provider ID, default model, and configured model names without exposing credentials
|
||||
|
||||
### Requirement: AI provider management preserves secret boundaries
|
||||
AI provider management SHALL reject raw key material in request fields and SHALL never expose raw API keys in API responses or frontend-visible types.
|
||||
|
||||
#### Scenario: Raw key is submitted during update
|
||||
- **WHEN** a create or update request includes raw key material instead of a secret reference in `apiKeyRef`
|
||||
- **THEN** the platform MUST reject the request with a validation error and MUST NOT persist the provider
|
||||
|
||||
#### Scenario: Provider is returned to UI
|
||||
- **WHEN** the backend or frontend API client returns provider data
|
||||
- **THEN** the response/type MUST include `apiKeyRef` only and MUST NOT include `apiKey`, `rawApiKey`, or equivalent raw credential fields
|
||||
|
||||
### Requirement: AI provider service owns management invariants
|
||||
The platform service layer SHALL own AI provider update, status, local test, and model-list behavior rather than implementing those rules directly in HTTP handlers.
|
||||
|
||||
#### Scenario: Management handler receives request
|
||||
- **WHEN** an AI provider management HTTP handler accepts a request
|
||||
- **THEN** it MUST decode named DTOs, call `service.Core`, and encode named DTO responses
|
||||
|
||||
#### Scenario: Missing provider is managed
|
||||
- **WHEN** a management action targets a missing provider ID
|
||||
- **THEN** the platform MUST return a stable `404` JSON error response
|
||||
|
||||
### Requirement: AI provider console page is functional
|
||||
The management console SHALL replace the placeholder AI provider page with a functional operational view for configured providers.
|
||||
|
||||
#### Scenario: Operator opens AI provider page
|
||||
- **WHEN** the AI provider page renders
|
||||
- **THEN** it MUST show provider counts, status distribution, configured model counts, and a provider table
|
||||
|
||||
#### Scenario: Operator edits provider form
|
||||
- **WHEN** an operator creates or edits a provider through the page form
|
||||
- **THEN** the page MUST submit named API requests and refresh or update the provider list without displaying raw key material
|
||||
|
||||
#### Scenario: Operator uses provider actions
|
||||
- **WHEN** an operator triggers enable/disable, test, or model-list actions
|
||||
- **THEN** the page MUST call the matching API client methods and display the redacted result state
|
||||
|
||||
### Requirement: Frontend contracts are centralized
|
||||
The frontend SHALL keep AI provider API types and client methods in `platform_web/api` and SHALL keep shared UI contracts out of page-local hidden types.
|
||||
|
||||
#### Scenario: Page consumes provider data
|
||||
- **WHEN** `AiProvidersPage` needs provider data or actions
|
||||
- **THEN** it MUST use named API types and `PlatformApiClient` methods instead of inline fetch contracts
|
||||
|
||||
#### Scenario: Frontend tests inspect provider types
|
||||
- **WHEN** frontend tests check provider response shapes
|
||||
- **THEN** they MUST confirm raw key fields are absent from returned provider data
|
||||
|
||||
### Requirement: AI provider management is verified end to end
|
||||
The change SHALL include backend API/service tests, frontend tests/build, a browser walkthrough, structure validation, and strict OpenSpec validation.
|
||||
|
||||
#### Scenario: Verification commands run
|
||||
- **WHEN** the change is complete
|
||||
- **THEN** `go test ./...` from `platform/`, frontend tests/build, `scripts/check-structure.sh`, and `openspec validate implement-ai-provider-management --strict` MUST pass
|
||||
|
||||
#### Scenario: Browser walkthrough runs
|
||||
- **WHEN** frontend AI provider page behavior is claimed complete
|
||||
- **THEN** a browser walkthrough MUST verify the page renders, exposes the AI provider workflow, and does not show raw credential fields
|
||||
@@ -0,0 +1,36 @@
|
||||
## 1. Backend Contracts And Service
|
||||
|
||||
- [x] 1.1 Add AI provider update, status, test, and model-list DTO contracts with redacted response shapes.
|
||||
- [x] 1.2 Extend `service.Core` with AI provider update, status, local test, and model-list methods using existing validators and repositories.
|
||||
|
||||
## 2. Backend API Surface
|
||||
|
||||
- [x] 2.1 Implement AI provider management routes for update, status, test, and models using named DTOs and service methods.
|
||||
- [x] 2.2 Update platform route/protocol documentation for implemented AI provider management routes and deferred live invocation.
|
||||
- [x] 2.3 Add backend service/API tests for update, enable/disable, test/models, missing resources, duplicate handling, and raw key rejection.
|
||||
|
||||
## 3. Frontend Contracts And Page
|
||||
|
||||
- [x] 3.1 Add centralized `platform_web/api` AI provider types and `PlatformApiClient` methods for list/create/update/status/test/models.
|
||||
- [x] 3.2 Replace the placeholder AI provider page with a functional operational management view using the API client and no raw key display.
|
||||
- [x] 3.3 Add frontend tests for page rendering, management actions, API client calls, and raw-key field absence.
|
||||
|
||||
## 4. Verification
|
||||
|
||||
- [x] 4.1 Run `go test ./...` from `platform/` and record evidence.
|
||||
- [x] 4.2 Run frontend tests/build from `platform_web/` and record evidence.
|
||||
- [x] 4.3 Run a browser walkthrough of the AI provider page and record evidence.
|
||||
- [x] 4.4 Run `scripts/check-structure.sh` and record evidence.
|
||||
- [x] 4.5 Run `openspec validate implement-ai-provider-management --strict` and record evidence.
|
||||
|
||||
## Evidence
|
||||
|
||||
- `go test ./domain ./dto`: passed.
|
||||
- `go test ./service ./api`: passed.
|
||||
- `go test ./...` from `platform/`: passed.
|
||||
- `npm test` from `platform_web/`: passed.
|
||||
- `npm run typecheck` from `platform_web/`: passed.
|
||||
- `npm run build` from `platform_web/`: passed.
|
||||
- Browser walkthrough with Playwright Chromium against `http://127.0.0.1:5173/#/aiProviders`: passed; rendered AI provider management, created `Browser Check Provider`, tested metadata, toggled status, and verified visible text did not contain `rawApiKey`, `api_key=`, `Bearer `, or `sk-`.
|
||||
- `scripts/check-structure.sh`: passed.
|
||||
- `openspec validate implement-ai-provider-management --strict`: passed.
|
||||
Reference in New Issue
Block a user