fix(settings): de-duplicate LLM Profile attributes in the "All" tab (#16154)

Co-authored-by: Engel Nyst <engel.nyst@gmail.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
🐾 smolpaws
2026-07-29 20:39:27 +02:00
committed by GitHub
co-authored by Engel Nyst Claude Opus 4.8
parent 7fa7b16968
commit a2fef1d73f
2 changed files with 58 additions and 1 deletions
@@ -181,6 +181,53 @@ describe("SdkSectionPage", () => {
).toBeInTheDocument();
});
it("renders each field once when the schema has duplicate sections for a key", async () => {
// The combined AgentSettings schema emits an "llm" section for each agent
// variant ("openhands" and "acp") with identical field keys. Only the first
// is used; without de-duplication every field would render twice (and React
// would warn about duplicate keys).
const llmSection = {
key: "llm",
label: "LLM",
fields: [
{
key: "llm.api_version",
label: "API Version",
section: "llm",
section_label: "LLM",
value_type: "string" as const,
default: null,
choices: [],
depends_on: [],
prominence: "minor" as const,
secret: false,
required: false,
},
],
};
const schema: NonNullable<Settings["agent_settings_schema"]> = {
model_name: "AgentSettings",
sections: [llmSection, { ...llmSection }],
};
vi.spyOn(SettingsService, "getSettings").mockResolvedValue(
buildSettings({
agent_settings_schema: schema,
agent_settings: {},
}),
);
renderSdkSectionPage({
settingsSources: [
{ settingsSource: "agent_settings", sectionKeys: ["llm"] },
],
getInitialView: () => "all",
});
const fields = await screen.findAllByTestId("sdk-settings-llm.api_version");
expect(fields).toHaveLength(1);
});
it("preserves the selected view when parent rerenders with the same settings", async () => {
const schema: NonNullable<Settings["agent_settings_schema"]> = {
model_name: "AgentSettings",
@@ -299,9 +299,19 @@ export function SdkSectionPage({
return { ...src, filteredSchema: null };
}
const sectionSet = new Set(src.sectionKeys);
// The agent schema can carry more than one section per key — e.g. the
// combined AgentSettings schema emits an "llm" section for both the
// "openhands" and "acp" variants. Only the first (openhands) is used,
// so keep the first section per key; otherwise every field renders
// twice and React sees duplicate section keys.
const seenKeys = new Set<string>();
const filteredSchema: SettingsSchema = {
...schema,
sections: schema.sections.filter((s) => sectionSet.has(s.key)),
sections: schema.sections.filter((s) => {
if (!sectionSet.has(s.key) || seenKeys.has(s.key)) return false;
seenKeys.add(s.key);
return true;
}),
};
return { ...src, filteredSchema };
}),