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.
47 lines
1.5 KiB
JavaScript
47 lines
1.5 KiB
JavaScript
// The classifier key form's pure logic: which key a runtime means, the checks
|
|
// before a save, and the line saying whether a key is stored. Run by
|
|
// `npm test`, which Node runs with its built-in test runner and type
|
|
// stripping, so the `.ts` module is imported as it is.
|
|
import assert from "node:assert/strict";
|
|
import { test } from "node:test";
|
|
import {
|
|
MAX_KEY_BYTES,
|
|
keyOf,
|
|
keyProblem,
|
|
keyStatus,
|
|
} from "../src/pages/review-settings/KeyTypes.ts";
|
|
|
|
const keys = {
|
|
api_key: { set: true, updated: "2026-11-11T10:00:00Z" },
|
|
acp: { set: false, updated: null },
|
|
};
|
|
|
|
test("a runtime means its own key", () => {
|
|
assert.equal(keyOf(keys, "api-key"), keys.api_key);
|
|
assert.equal(keyOf(keys, "acp"), keys.acp);
|
|
});
|
|
|
|
test("an empty key or one with whitespace is not ready to save", () => {
|
|
assert.notEqual(keyProblem(""), null);
|
|
assert.notEqual(keyProblem(" "), null);
|
|
assert.notEqual(keyProblem("two words"), null);
|
|
assert.equal(keyProblem("sk-ant-abc"), null);
|
|
});
|
|
|
|
test("a pasted trailing newline is fine", () => {
|
|
assert.equal(keyProblem("sk-ant-abc\n"), null);
|
|
});
|
|
|
|
test("a key over the limit is not ready to save", () => {
|
|
assert.equal(keyProblem("k".repeat(MAX_KEY_BYTES)), null);
|
|
assert.notEqual(keyProblem("k".repeat(MAX_KEY_BYTES + 1)), null);
|
|
});
|
|
|
|
test("the status says whether a key is stored and when it changed", () => {
|
|
assert.equal(keyStatus(keys.acp), "not set");
|
|
assert.equal(
|
|
keyStatus(keys.api_key),
|
|
"set, last changed 2026-11-11T10:00:00Z",
|
|
);
|
|
assert.equal(keyStatus({ set: true, updated: null }), "set");
|
|
});
|