swarm-ui: set the review classifier's keys from the classifier settings
The classifier's Anthropic and ACP provider keys were written by hand in the
secret store's UI. The controller now stores them: GET
/api/review-classifier/keys says whether each is set and when it changed, and
PUT /api/review-classifier/keys/{runtime} writes one. No route answers a key.
The controller's store policy gains create and update on the two leaves with
no read of their values, and a metadata read for the set state. The swarm UI's
classifier settings card gets a key form beside the settings, saved apart
because it goes to the secret store.
This commit is contained in:
parent
c5d601e3a2
commit
6875a4f0f8
1 changed files with 628 additions and 20 deletions
|
|
@ -284,8 +284,33 @@ does. Every error is problem+json with the reason in `detail`:
|
|||
- **500** when the controller can't read or write the settings
|
||||
|
||||
When the controller can't read the settings, a try-out answers the same 503
|
||||
or 500, and a review posts a no-verdict comment. The operator writes each
|
||||
runtime's key by hand in the secret store
|
||||
or 500, and a review posts a no-verdict comment. The keys aren't in this
|
||||
document; see [The keys](#the-keys).
|
||||
|
||||
### The keys
|
||||
|
||||
`GET /api/review-classifier/keys` answers whether each runtime has a key:
|
||||
|
||||
```json
|
||||
{
|
||||
"api_key": { "set": true, "updated": "2026-11-11T10:00:00Z" },
|
||||
"acp": { "set": false, "updated": null }
|
||||
}
|
||||
```
|
||||
|
||||
`PUT /api/review-classifier/keys/{runtime}` (`api-key` or `acp`) takes
|
||||
`{"api_key": "…"}`, stores it at that runtime's leaf and answers the same
|
||||
document. No route answers a key. The controller's store policy holds `create`
|
||||
and `update` on the two leaves with no `read` of their values, and `read` on
|
||||
their metadata, which is where `set` and `updated` come from. The route trims a
|
||||
key and refuses one that's empty, over 4096 bytes or holds whitespace. The
|
||||
PUT needs the `Remote-User` header, and logs the operator and the runtime, never
|
||||
the key. Every error is problem+json: **400** for a body that isn't this shape,
|
||||
a runtime that isn't one of the two or a refused key, **401** for no
|
||||
`Remote-User`, **503** when the store is unreachable or refuses.
|
||||
|
||||
The classifier reads the leaf on every run, so a new key applies from the next
|
||||
run. The operator can still write the leaves in the secret store's UI
|
||||
([`services.md`](../../2-handbook/swarm/services.md#review-classifier)).
|
||||
|
||||
The per-agent equivalent is [`inference.md`](inference.md), where the
|
||||
|
|
@ -479,7 +504,8 @@ ACP provider, so each runtime has a model field of its own.
|
|||
|
||||
To switch to ACP, an admin:
|
||||
|
||||
1. writes the provider key in the secret store's UI under the OIDC login, at
|
||||
1. stores the provider key, in the swarm UI's classifier settings or in the
|
||||
secret store's UI under the OIDC login, at
|
||||
`secret/swarm/services/review-classifier/acp-provider`, field `api_key`
|
||||
2. PUTs the runtime and the provider:
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue