test: cover browser snapshot labels and efficient mode
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
- Security: add detect-secrets CI scan and baseline guidance. (#227) — thanks @Hyaxia.
|
||||
|
||||
### Fixes
|
||||
- Browser: add tests for snapshot labels/efficient query params and labeled image responses.
|
||||
- Doctor: avoid re-adding WhatsApp config when only legacy ack reactions are set. (#927, fixes #900) — thanks @grp06.
|
||||
- Agents: scrub tuple `items` schemas for Gemini tool calls. (#926, fixes #746) — thanks @grp06.
|
||||
- Embedded runner: suppress raw API error payloads from replies. (#924) — thanks @grp06.
|
||||
|
||||
@@ -80,14 +80,9 @@ function resolveProviderToolPolicy(params: {
|
||||
const normalizedProvider = normalizeProviderKey(provider);
|
||||
const rawModelId = params.modelId?.trim().toLowerCase();
|
||||
const fullModelId =
|
||||
rawModelId && !rawModelId.includes("/")
|
||||
? `${normalizedProvider}/${rawModelId}`
|
||||
: rawModelId;
|
||||
rawModelId && !rawModelId.includes("/") ? `${normalizedProvider}/${rawModelId}` : rawModelId;
|
||||
|
||||
const candidates = [
|
||||
...(fullModelId ? [fullModelId] : []),
|
||||
normalizedProvider,
|
||||
];
|
||||
const candidates = [...(fullModelId ? [fullModelId] : []), normalizedProvider];
|
||||
|
||||
for (const key of candidates) {
|
||||
const match = lookup.get(key);
|
||||
|
||||
@@ -125,8 +125,7 @@ export function createClawdbotCodingTools(options?: {
|
||||
});
|
||||
const profilePolicy = resolveToolProfilePolicy(profile);
|
||||
const providerProfilePolicy = resolveToolProfilePolicy(providerProfile);
|
||||
const scopeKey =
|
||||
options?.exec?.scopeKey ?? (agentId ? `agent:${agentId}` : undefined);
|
||||
const scopeKey = options?.exec?.scopeKey ?? (agentId ? `agent:${agentId}` : undefined);
|
||||
const subagentPolicy =
|
||||
isSubagentSessionKey(options?.sessionKey) && options?.sessionKey
|
||||
? resolveSubagentToolPolicy(options.config)
|
||||
@@ -240,9 +239,7 @@ export function createClawdbotCodingTools(options?: {
|
||||
hasRepliedRef: options?.hasRepliedRef,
|
||||
}),
|
||||
];
|
||||
const toolsFiltered = profilePolicy
|
||||
? filterToolsByPolicy(tools, profilePolicy)
|
||||
: tools;
|
||||
const toolsFiltered = profilePolicy ? filterToolsByPolicy(tools, profilePolicy) : tools;
|
||||
const providerProfileFiltered = providerProfilePolicy
|
||||
? filterToolsByPolicy(toolsFiltered, providerProfilePolicy)
|
||||
: toolsFiltered;
|
||||
|
||||
@@ -52,6 +52,17 @@ vi.mock("../../config/config.js", () => ({
|
||||
loadConfig: vi.fn(() => ({ browser: {} })),
|
||||
}));
|
||||
|
||||
const toolCommonMocks = vi.hoisted(() => ({
|
||||
imageResultFromFile: vi.fn(),
|
||||
}));
|
||||
vi.mock("./common.js", async () => {
|
||||
const actual = await vi.importActual<typeof import("./common.js")>("./common.js");
|
||||
return {
|
||||
...actual,
|
||||
imageResultFromFile: toolCommonMocks.imageResultFromFile,
|
||||
};
|
||||
});
|
||||
|
||||
import { DEFAULT_AI_SNAPSHOT_MAX_CHARS } from "../../browser/constants.js";
|
||||
import { createBrowserTool } from "./browser-tool.js";
|
||||
|
||||
@@ -103,3 +114,47 @@ describe("browser tool snapshot maxChars", () => {
|
||||
expect(Object.hasOwn(opts ?? {}, "maxChars")).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe("browser tool snapshot labels", () => {
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
});
|
||||
|
||||
it("returns image + text when labels are requested", async () => {
|
||||
const tool = createBrowserTool();
|
||||
const imageResult = {
|
||||
content: [
|
||||
{ type: "text", text: "label text" },
|
||||
{ type: "image", data: "base64", mimeType: "image/png" },
|
||||
],
|
||||
details: { path: "/tmp/snap.png" },
|
||||
};
|
||||
|
||||
toolCommonMocks.imageResultFromFile.mockResolvedValueOnce(imageResult);
|
||||
browserClientMocks.browserSnapshot.mockResolvedValueOnce({
|
||||
ok: true,
|
||||
format: "ai",
|
||||
targetId: "t1",
|
||||
url: "https://example.com",
|
||||
snapshot: "label text",
|
||||
imagePath: "/tmp/snap.png",
|
||||
});
|
||||
|
||||
const result = await tool.execute?.(null, {
|
||||
action: "snapshot",
|
||||
format: "ai",
|
||||
labels: true,
|
||||
});
|
||||
|
||||
expect(toolCommonMocks.imageResultFromFile).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
path: "/tmp/snap.png",
|
||||
extraText: "label text",
|
||||
}),
|
||||
);
|
||||
expect(result).toEqual(imageResult);
|
||||
expect(result?.content).toHaveLength(2);
|
||||
expect(result?.content?.[0]).toMatchObject({ type: "text", text: "label text" });
|
||||
expect(result?.content?.[1]).toMatchObject({ type: "image" });
|
||||
});
|
||||
});
|
||||
|
||||
@@ -49,6 +49,40 @@ describe("browser client", () => {
|
||||
).rejects.toThrow(/409: conflict/i);
|
||||
});
|
||||
|
||||
it("adds labels + efficient mode query params to snapshots", async () => {
|
||||
const calls: string[] = [];
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
vi.fn(async (url: string) => {
|
||||
calls.push(url);
|
||||
return {
|
||||
ok: true,
|
||||
json: async () => ({
|
||||
ok: true,
|
||||
format: "ai",
|
||||
targetId: "t1",
|
||||
url: "https://x",
|
||||
snapshot: "ok",
|
||||
}),
|
||||
} as unknown as Response;
|
||||
}),
|
||||
);
|
||||
|
||||
await expect(
|
||||
browserSnapshot("http://127.0.0.1:18791", {
|
||||
format: "ai",
|
||||
labels: true,
|
||||
mode: "efficient",
|
||||
}),
|
||||
).resolves.toMatchObject({ ok: true, format: "ai" });
|
||||
|
||||
const snapshotCall = calls.find((url) => url.includes("/snapshot?"));
|
||||
expect(snapshotCall).toBeTruthy();
|
||||
const parsed = new URL(snapshotCall as string);
|
||||
expect(parsed.searchParams.get("labels")).toBe("1");
|
||||
expect(parsed.searchParams.get("mode")).toBe("efficient");
|
||||
});
|
||||
|
||||
it("uses the expected endpoints + methods for common calls", async () => {
|
||||
const calls: Array<{ url: string; init?: RequestInit }> = [];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user