diff --git a/electron/ai-edition/agent-tools.test.ts b/electron/ai-edition/agent-tools.test.ts index c105d2e4b..55a9c17bd 100644 --- a/electron/ai-edition/agent-tools.test.ts +++ b/electron/ai-edition/agent-tools.test.ts @@ -10,6 +10,7 @@ import { ZOOM_DEPTH_SCALES } from "../../src/lib/ai-edition/timeline/zoom-scale" import { zoomScaleLimit } from "../../src/native/sceneDescription"; import { type AgentToolOptions, + addZoomArgs, executeAgentTool, isMutatingTool, MUTATING_TOOL_NAMES, @@ -3342,6 +3343,23 @@ describe("region tools reach the inspector's settings (#1180)", () => { expect(both.ok).toBe(false); }); + it("takes customScale alone wherever the arguments were parsed first", () => { + // The MCP server and the in-app agent hand the tool its arguments through the same schema, + // and addZooms hands each region to addZoom parsed. A default depth filled in there read as + // "depth and customScale both passed", so a free level could never be set in one call. + const zoomOnly = { startSec: 2, endSec: 4, customScale: 1.6 }; + const parsed = run(fixtureDocument(), "addZoom", addZoomArgs.parse(zoomOnly)); + expect(parsed.ok).toBe(true); + expect(parsed.document?.zoomRanges[0]).toMatchObject({ customScale: 1.6 }); + const batch = run(fixtureDocument(), "addZooms", { regions: [zoomOnly] }); + expect(batch.ok).toBe(true); + expect(batch.document?.zoomRanges[0]).toMatchObject({ customScale: 1.6 }); + // Neither level given: the default depth still applies. + const plain = run(fixtureDocument(), "addZoom", addZoomArgs.parse({ startSec: 2, endSec: 4 })); + expect(plain.document?.zoomRanges[0]).toMatchObject({ depth: 3 }); + expect(plain.document?.zoomRanges[0]).not.toHaveProperty("customScale"); + }); + it("reads an annotation back in the terms its writes take", () => { const added = run(fixtureDocument(), "addAnnotation", { startSec: 1, diff --git a/electron/ai-edition/agent-tools.ts b/electron/ai-edition/agent-tools.ts index 50bb5de41..c9b64ecb6 100644 --- a/electron/ai-edition/agent-tools.ts +++ b/electron/ai-edition/agent-tools.ts @@ -791,7 +791,12 @@ const customScaleSchema = z export const addZoomArgs = z.object({ startSec: secondsSchema, endSec: secondsSchema, - depth: depthSchema.default(3), + // No schema default: the MCP server, the in-app agent and addZooms all parse the arguments + // before the tool runs, and a default filled in there reads as a depth passed next to + // customScale. The handler applies 3 when neither level is given. + depth: depthSchema + .optional() + .describe("Defaults to 3 when neither depth nor customScale is given."), focus: focusSchema.default({ cx: 0.5, cy: 0.5 }), rotationPreset: rotationPresetSchema.default("none"), focusMode: focusModeSchema.default("manual"), @@ -2897,7 +2902,7 @@ export function executeAgentTool( id: createId("zoom"), startMs, endMs, - depth: parsed.data.depth as 1 | 2 | 3 | 4 | 5 | 6, + depth: (parsed.data.depth ?? 3) as 1 | 2 | 3 | 4 | 5 | 6, ...level, focus: parsed.data.focus, focusMode: parsed.data.focusMode,