mirror of
https://github.com/OpenHands/OpenHands.git
synced 2026-10-07 13:38:55 +08:00
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:
co-authored by
Engel Nyst
Claude Opus 4.8
parent
7fa7b16968
commit
a2fef1d73f
@@ -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 };
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user