feat(cloud): manage LLM providers in database
Tests / Test passed: 664

This commit is contained in:
2026-07-14 00:31:47 +08:00
parent b613a315ff
commit a166ffd8a4
35 changed files with 2432 additions and 204 deletions
+39
View File
@@ -3,6 +3,7 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import {
AUTH_INVALID_EVENT,
createLlmProviderProfile,
listDevices,
login,
registerPlugin,
@@ -74,6 +75,44 @@ describe("Cloud Console API authentication", () => {
);
});
it("sends a Provider profile write through the CSRF-protected management API", async () => {
document.cookie = "amcp_csrf=csrf-value; path=/";
vi.mocked(fetch).mockResolvedValueOnce(
response({
id: "provider-a",
name: "OpenAI compatible",
provider_type: "openai-compatible",
model: "model-a",
base_url: "https://compat.example/v1",
timeout_seconds: 30,
enabled: true,
revision: 1,
has_api_key: true,
key_last_rotated_at: "2026-01-01T00:00:00+00:00",
created_at: "2026-01-01T00:00:00+00:00",
updated_at: "2026-01-01T00:00:00+00:00",
active: false,
}),
);
await createLlmProviderProfile({
name: "OpenAI compatible",
provider_type: "openai-compatible",
model: "model-a",
base_url: "https://compat.example/v1",
timeout_seconds: 30,
api_key: "secret-value",
});
expect(fetch).toHaveBeenCalledWith(
expect.stringMatching(/\/v1\/planner\/providers$/),
expect.objectContaining({
method: "POST",
headers: expect.objectContaining({ "X-CSRF-Token": "csrf-value" }),
}),
);
});
it("invalidates the session only on 401", async () => {
const invalidated = vi.fn();
window.addEventListener(AUTH_INVALID_EVENT, invalidated);