fix(control-ui): support raw edits from editable config

This commit is contained in:
BlackFrameAI
2026-05-25 19:11:31 -06:00
committed by clawsweeper
parent 34d862d45d
commit 24eba3a7e6
3 changed files with 30 additions and 7 deletions
+4 -1
View File
@@ -1198,7 +1198,10 @@ export function renderApp(state: AppViewState) {
gatewayUrl: state.settings.gatewayUrl,
assistantName: state.assistantName,
configPath: state.configSnapshot?.path ?? null,
rawAvailable: typeof state.configSnapshot?.raw === "string",
rawAvailable:
typeof state.configSnapshot?.raw === "string" ||
!!state.configSnapshot?.config ||
!!state.configForm,
} satisfies Omit<
ConfigProps,
| "formMode"
+25 -2
View File
@@ -183,7 +183,7 @@ describe("applyConfigSnapshot", () => {
expect(state.configDraftBaseHash).toBe("hash-remote");
});
it("forces form mode when the snapshot does not include raw text", () => {
it("keeps raw mode when editable config can be serialized without raw text", () => {
const state = createState();
state.configFormMode = "raw";
@@ -195,7 +195,7 @@ describe("applyConfigSnapshot", () => {
raw: null,
});
expect(state.configFormMode).toBe("form");
expect(state.configFormMode).toBe("raw");
expect(state.configRaw).toBe('{\n "gateway": {\n "mode": "local"\n }\n}\n');
});
});
@@ -707,6 +707,29 @@ describe("applyConfig", () => {
});
describe("saveConfig", () => {
it("submits generated raw text when the snapshot did not include raw text", async () => {
const request = createRequestWithConfigGet();
const state = createState();
state.connected = true;
state.client = { request } as unknown as ConfigState["client"];
state.configFormMode = "raw";
applyConfigSnapshot(state, {
hash: "hash-generated-raw",
sourceConfig: { gateway: { mode: "local" } },
config: { gateway: { mode: "local", runtimeOnly: true } },
valid: true,
issues: [],
raw: null,
});
await saveConfig(state);
expect(request).toHaveBeenCalledWith("config.set", {
raw: '{\n "gateway": {\n "mode": "local"\n }\n}\n',
baseHash: "hash-generated-raw",
});
});
it("submits the original draft base hash after a dirty config refresh", async () => {
const request = createRequestWithConfigGet();
const state = createState();
+1 -4
View File
@@ -113,7 +113,7 @@ export function applyConfigSnapshot(
const draftBaseHash = state.configDraftBaseHash ?? state.configSnapshot?.hash ?? null;
state.configSnapshot = snapshot;
const editableConfig = resolveEditableSnapshotConfig(snapshot);
const rawAvailable = typeof snapshot.raw === "string";
const rawAvailable = typeof snapshot.raw === "string" || !!editableConfig || !!state.configForm;
if (!rawAvailable && state.configFormMode === "raw") {
state.configFormMode = "form";
}
@@ -161,9 +161,6 @@ function asJsonSchema(value: unknown): JsonSchema | null {
* gateway's Zod validation always sees correctly typed values.
*/
function serializeFormForSubmit(state: ConfigState): string {
if (state.configFormMode === "raw" && typeof state.configSnapshot?.raw !== "string") {
throw new Error("Raw config editing is unavailable for this snapshot. Switch to Form mode.");
}
if (state.configFormMode !== "form" || !state.configForm) {
return state.configRaw;
}