fix(tools): keep web_search top-level under xdev
web_search is a discoverable built-in, so with tools.xdev defaulting to true createTools mounted it under xd:// and dropped it from the top-level toolset. Models that call web_search directly got "Tool web_search not found" on default configs. Pin it in XDEV_KEEP_TOP_LEVEL so it stays a direct-callable tool while other discoverable tools keep mounting. Fixes #5973
This commit is contained in:
@@ -2,6 +2,10 @@
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### Fixed
|
||||
|
||||
- Fixed `web_search` being unreachable under default config: with `tools.xdev: true`, the discoverable `web_search` tool was mounted under `xd://` and dropped from the top-level toolset, so models calling it directly got "Tool web_search not found". It is now pinned top-level via `XDEV_KEEP_TOP_LEVEL` while other discoverable tools keep mounting under `xd://` ([#5973](https://github.com/can1357/oh-my-pi/issues/5973)).
|
||||
|
||||
## [17.0.4] - 2026-07-18
|
||||
|
||||
### Fixed
|
||||
|
||||
@@ -38,11 +38,18 @@ import { ToolError } from "./tool-errors";
|
||||
/**
|
||||
* Discoverable built-ins that must stay top-level even when xdev mounting is
|
||||
* active: `todo` feeds the todo prelude/prewalk machinery, `ask` is the
|
||||
* model's user-interaction affordance, and `grep` is the redirect target of
|
||||
* the bash interceptor rules — each loses its harness integration if hidden
|
||||
* behind dispatch.
|
||||
* model's user-interaction affordance, `grep` is the redirect target of the
|
||||
* bash interceptor rules, and `web_search` is invoked directly by most models
|
||||
* (which have no notion of the `xd://` protocol) so hiding it behind dispatch
|
||||
* makes it unreachable in practice (issue #5973) — each loses its harness
|
||||
* integration or usability if hidden behind dispatch.
|
||||
*/
|
||||
export const XDEV_KEEP_TOP_LEVEL: Record<string, true> = { todo: true, ask: true, grep: true };
|
||||
export const XDEV_KEEP_TOP_LEVEL: Record<string, true> = {
|
||||
todo: true,
|
||||
ask: true,
|
||||
grep: true,
|
||||
web_search: true,
|
||||
};
|
||||
|
||||
/**
|
||||
* Tools that carry the `xd://` transport itself and therefore can never be
|
||||
|
||||
@@ -206,3 +206,22 @@ describe("read and write route xd:// device URLs", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("web_search stays top-level under xdev", () => {
|
||||
it("keeps web_search a direct tool and off the xd:// registry with default config", async () => {
|
||||
const tempDir = await fs.mkdtemp(path.join(os.tmpdir(), "write-xdev-websearch-"));
|
||||
try {
|
||||
const session = xdevSession(tempDir);
|
||||
// Default config: tools.xdev is on.
|
||||
expect(session.settings.get("tools.xdev")).toBe(true);
|
||||
const tools = await createTools(session);
|
||||
// Regression for #5973: models call web_search directly, so it must
|
||||
// remain a top-level function and never mount behind the xd:// device.
|
||||
expect(tools.some(entry => entry.name === "web_search")).toBe(true);
|
||||
const mounted = session.xdevRegistry ? [...session.xdevRegistry.list()].map(t => t.name) : [];
|
||||
expect(mounted).not.toContain("web_search");
|
||||
} finally {
|
||||
await removeWithRetries(tempDir);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user