Merge PR #7814: fix(coding-agent): clean up legacy Exa and computer settings (@chessl)

This commit is contained in:
can1357
2026-08-07 13:39:52 +02:00
5 changed files with 108 additions and 34 deletions
+5
View File
@@ -90,6 +90,11 @@
- Normalized resolved file paths in `read` summary recovery selectors, PDF image handles, and notebook errors so suffix-matched input does not teach agents malformed follow-up paths ([#7788](https://github.com/can1357/oh-my-pi/issues/7788)).
### Changed
- Consolidated Exa web-search enablement on `exa.enabled`; legacy `exa.enableSearch` values migrate automatically, and the obsolete Researcher and Websets settings have been removed.
- Removed stale `computer.backend` values during config migration.
## [17.2.9] - 2026-08-05
### Breaking Changes
@@ -5406,19 +5406,13 @@ export const SETTINGS_SCHEMA = {
// Exa
"exa.enabled": {
type: "boolean",
default: true,
ui: { tab: "providers", group: "Services", label: "Exa", description: "Master toggle for all Exa search tools" },
},
"exa.enableSearch": {
type: "boolean",
default: true,
ui: {
tab: "providers",
group: "Services",
label: "Exa Search",
description: "Enable Exa basic search, deep search, code search, and crawl tools",
label: "Exa",
description: "Enable the Exa web search provider",
},
},
@@ -5433,28 +5427,6 @@ export const SETTINGS_SCHEMA = {
},
},
"exa.enableResearcher": {
type: "boolean",
default: false,
ui: {
tab: "providers",
group: "Services",
label: "Exa Researcher",
description: "Enable the Exa researcher tool for AI-powered deep research",
},
},
"exa.enableWebsets": {
type: "boolean",
default: false,
ui: {
tab: "providers",
group: "Services",
label: "Exa Websets",
description: "Enable Exa webset management and enrichment tools",
},
},
// SearXNG
"searxng.endpoint": {
type: "string",
@@ -5794,10 +5766,7 @@ export interface TtsrSettings {
export interface ExaSettings {
enabled: boolean;
enableSearch: boolean;
searchDelayMs: number;
enableResearcher: boolean;
enableWebsets: boolean;
}
export interface StatusLineSettings {
@@ -1860,6 +1860,52 @@ export class Settings {
: undefined,
);
// Consolidate the retired Exa suite toggles onto the sole remaining
// provider switch. The old runtime required both `enabled` and
// `enableSearch`, so preserve that AND semantics when both are present.
// Researcher and Websets were removed with the standalone Exa tools.
const exaObj = isRecord(raw.exa) ? raw.exa : undefined;
const exaEnabledValues = [
exaObj?.enabled,
raw["exa.enabled"],
exaObj?.enableSearch,
raw["exa.enableSearch"],
].filter((value): value is boolean => typeof value === "boolean");
const hasFlatExaSetting =
"exa.enabled" in raw ||
"exa.enableSearch" in raw ||
"exa.enableResearcher" in raw ||
"exa.enableWebsets" in raw;
if (exaObj || hasFlatExaSetting) {
const exaRoot = exaObj ?? {};
if (exaEnabledValues.length > 0) {
exaRoot.enabled = exaEnabledValues.every(Boolean);
}
delete exaRoot.enableSearch;
delete exaRoot.enableResearcher;
delete exaRoot.enableWebsets;
if (Object.keys(exaRoot).length > 0) {
raw.exa = exaRoot;
} else {
delete raw.exa;
}
delete raw["exa.enabled"];
delete raw["exa.enableSearch"];
delete raw["exa.enableResearcher"];
delete raw["exa.enableWebsets"];
}
// computer.backend and model-specific controller routing were removed
// when the computer tool moved to one native desktop implementation.
const computerObj = isRecord(raw.computer) ? raw.computer : undefined;
if (computerObj && "backend" in computerObj) {
delete computerObj.backend;
if (Object.keys(computerObj).length === 0) {
delete raw.computer;
}
}
delete raw["computer.backend"];
return raw;
}
@@ -464,7 +464,7 @@ export class ExaProvider extends SearchProvider {
#settingsAllowSearch(): boolean {
try {
if (settings.get("exa.enabled") === false || settings.get("exa.enableSearch") === false) {
if (settings.get("exa.enabled") === false) {
return false;
}
} catch {
@@ -919,6 +919,60 @@ describe("Settings", () => {
});
describe("migrations", () => {
it("consolidates legacy Exa suite toggles onto exa.enabled", async () => {
await writeSettings({
exa: {
enabled: true,
enableSearch: false,
enableResearcher: true,
enableWebsets: true,
},
});
const settings = await Settings.init({ cwd: projectDir, agentDir });
expect(settings.get("exa.enabled")).toBe(false);
settings.set("display.showTokenUsage", true);
await settings.flush();
expect((await readSettings()).exa).toEqual({ enabled: false });
});
it("migrates quoted dotted Exa toggles and removes obsolete suite settings", async () => {
await Bun.write(
getConfigPath(),
`"exa.enabled": true\n"exa.enableSearch": false\n"exa.enableResearcher": true\n"exa.enableWebsets": true\n`,
);
const settings = await Settings.init({ cwd: projectDir, agentDir });
expect(settings.get("exa.enabled")).toBe(false);
settings.set("display.showTokenUsage", true);
await settings.flush();
expect((await readSettings()).exa).toEqual({ enabled: false });
});
it("removes the legacy Exa block when it contains only retired suite toggles", async () => {
await writeSettings({ exa: { enableResearcher: true, enableWebsets: true } });
const settings = await Settings.init({ cwd: projectDir, agentDir });
expect(settings.get("exa.enabled")).toBe(true);
settings.set("display.showTokenUsage", true);
await settings.flush();
expect((await readSettings()).exa).toBeUndefined();
});
it("removes the retired computer backend setting", async () => {
await writeSettings({ computer: { backend: "auto", enabled: true }, "computer.backend": "native" });
const settings = await Settings.init({ cwd: projectDir, agentDir });
expect(settings.get("computer.enabled")).toBe(true);
settings.set("display.showTokenUsage", true);
await settings.flush();
expect((await readSettings()).computer).toEqual({ enabled: true });
});
it("maps removed atom edit mode settings to hashline", async () => {
await writeSettings({
edit: {