Fix LLM validation and dashboard health hot paths
This commit is contained in:
@@ -142,10 +142,15 @@
|
||||
togglingProviderIds = new Set(togglingProviderIds);
|
||||
|
||||
try {
|
||||
await requestApi(`/llm/providers/${provider.id}`, "PUT", {
|
||||
...provider,
|
||||
const updatePayload = {
|
||||
id: provider.id,
|
||||
name: provider.name,
|
||||
provider_type: provider.provider_type,
|
||||
base_url: provider.base_url,
|
||||
default_model: provider.default_model,
|
||||
is_active: provider.is_active,
|
||||
});
|
||||
};
|
||||
await requestApi(`/llm/providers/${provider.id}`, "PUT", updatePayload);
|
||||
} catch (err) {
|
||||
provider.is_active = previousState;
|
||||
providers = [...providers];
|
||||
|
||||
@@ -46,6 +46,15 @@ describe('ProviderConfig edit interaction contract', () => {
|
||||
expect(source).toContain('await requestApi(`/llm/providers/${provider.id}`, "DELETE")');
|
||||
expect(source).toContain('onclick={() => handleDelete(provider)}');
|
||||
});
|
||||
|
||||
it('does not forward masked api_key when toggling provider activation', () => {
|
||||
const source = fs.readFileSync(COMPONENT_PATH, 'utf-8');
|
||||
|
||||
expect(source).toContain('const updatePayload = {');
|
||||
expect(source).toContain('provider_type: provider.provider_type');
|
||||
expect(source).toContain('default_model: provider.default_model');
|
||||
expect(source).not.toContain('await requestApi(`/llm/providers/${provider.id}`, "PUT", {\n ...provider,');
|
||||
});
|
||||
});
|
||||
// [/DEF:provider_config_edit_contract_tests:Function]
|
||||
// [/DEF:frontend.src.components.llm.__tests__.provider_config_integration:Module]
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
* @TEST_FIXTURE init_state -> {"taskId": "task-1"}
|
||||
* @TEST_INVARIANT correct_fetch -> verifies: [init_state]
|
||||
*/
|
||||
import { onDestroy, onMount } from "svelte";
|
||||
import { onDestroy, onMount, untrack } from "svelte";
|
||||
import { page } from "$app/state";
|
||||
import { goto } from "$app/navigation";
|
||||
import { api } from "$lib/api.js";
|
||||
@@ -171,7 +171,10 @@
|
||||
);
|
||||
|
||||
$effect(() => {
|
||||
void loadScreenshotBlobUrls(screenshotPaths);
|
||||
const paths = screenshotPaths;
|
||||
untrack(() => {
|
||||
void loadScreenshotBlobUrls(paths);
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
// [DEF:frontend.src.routes.reports.llm.taskid.report_page_contract_test:Module]
|
||||
// @TIER: STANDARD
|
||||
// @SEMANTICS: llm-report, svelte-effect, screenshot-loading, regression-test
|
||||
// @PURPOSE: Protect the LLM report page from self-triggering screenshot load effects.
|
||||
// @LAYER: UI Tests
|
||||
// @RELATION: VERIFIES -> frontend/src/routes/reports/llm/[taskId]/+page.svelte
|
||||
|
||||
import { describe, it, expect } from "vitest";
|
||||
import fs from "node:fs";
|
||||
import path from "node:path";
|
||||
|
||||
const PAGE_PATH = path.resolve(
|
||||
process.cwd(),
|
||||
"src/routes/reports/llm/[taskId]/+page.svelte",
|
||||
);
|
||||
|
||||
// [DEF:llm_report_screenshot_effect_contract:Function]
|
||||
// @TIER: STANDARD
|
||||
// @PURPOSE: Ensure screenshot loading stays untracked from blob-url mutation state.
|
||||
// @PRE: Report page source exists.
|
||||
// @POST: Contract fails if screenshot loading effect can subscribe to screenshotBlobUrls updates.
|
||||
describe("LLM report screenshot effect contract", () => {
|
||||
it("uses untrack around screenshot blob loading side effect", () => {
|
||||
const source = fs.readFileSync(PAGE_PATH, "utf-8");
|
||||
|
||||
expect(source).toContain('import { onDestroy, onMount, untrack } from "svelte";');
|
||||
expect(source).toContain("untrack(() => {");
|
||||
expect(source).toContain("void loadScreenshotBlobUrls(paths);");
|
||||
});
|
||||
});
|
||||
// [/DEF:llm_report_screenshot_effect_contract:Function]
|
||||
// [/DEF:frontend.src.routes.reports.llm.taskid.report_page_contract_test:Module]
|
||||
Reference in New Issue
Block a user