Skip to content

Commit 2edbb6d

Browse files
committed
fix(mcp): name the duplicated clip by id, and give every asset on a file its cursor read
Part of #1180.
1 parent b5dd6ef commit 2edbb6d

3 files changed

Lines changed: 25 additions & 7 deletions

File tree

‎electron/ai-edition/agent-tools.test.ts‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3607,6 +3607,18 @@ describe("clip structure (#1180)", () => {
36073607
expect(run(twoTakes(), "duplicateClip", { clipId: "clip_x" }).ok).toBe(false);
36083608
});
36093609

3610+
it("duplicateClip names the copy even when the clips before it fold together", () => {
3611+
// clip_1 and clip_2 already meet, so the pass after the copy makes them one clip and
3612+
// the copy is no longer at the original's index + 1.
3613+
const result = run(fixtureDocument(), "duplicateClip", { clipId: "clip_2" });
3614+
const { clipId } = JSON.parse(result.resultJson);
3615+
expect(result.ok).toBe(true);
3616+
expect((result.document as AxcutDocument).timeline.clips.map((c) => c.id)).toEqual([
3617+
"clip_1",
3618+
clipId,
3619+
]);
3620+
});
3621+
36103622
it("setClipRange crops a clip without touching its range, and the snapshot reads it back", () => {
36113623
const crop = { x: 0.1, y: 0.2, width: 0.5, height: 0.6 };
36123624
const result = run(twoTakes(), "setClipRange", { clipId: "clip_1", cropRegion: crop });

‎electron/ai-edition/agent-tools.ts‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2474,12 +2474,17 @@ export function executeAgentTool(
24742474
const parsed = duplicateClipArgs.safeParse(args);
24752475
if (!parsed.success) return failure(parsed.error.message);
24762476
const { clipId } = parsed.data;
2477-
const index = document.timeline.clips.findIndex((c) => c.id === clipId);
2478-
if (index < 0) return failure(`Unknown clip: ${clipId}. ${clipRoster(document)}`);
2477+
if (!document.timeline.clips.some((c) => c.id === clipId)) {
2478+
return failure(`Unknown clip: ${clipId}. ${clipRoster(document)}`);
2479+
}
24792480
// The editor's Duplicate: the copy right after the original, with its own copy of
24802481
// the original's cuts and anchored effects.
24812482
const next = duplicateClip(document, clipId, "agent", "");
2482-
const copy = next.timeline.clips[index + 1];
2483+
// By id, not position: the pass every clip edit ends with can fold clips that
2484+
// already met, which moves the positions.
2485+
const before = new Set(document.timeline.clips.map((c) => c.id));
2486+
const copy = next.timeline.clips.find((c) => !before.has(c.id));
2487+
if (!copy) return failure(`Clip ${clipId} could not be copied. Nothing was modified.`);
24832488
return {
24842489
ok: true,
24852490
document: next,

‎electron/ai-edition/deep-agent/service.ts‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -375,10 +375,11 @@ async function planAutoZooms(
375375
if (!cursor) return undefined;
376376
const telemetry: AutoZoomPlan["telemetry"] = {};
377377
const suggestions = await collectAutoZoomSuggestionsForDocument(document, async (videoPath) => {
378-
const asset = document.assets.find((a) => a.originalPath === videoPath);
379-
if (!asset) return [];
380-
const load = await readCursor(cursor, asset.id, videoPath);
381-
telemetry[asset.id] = load.status;
378+
// The plan asks by path; every asset on that file gets the verdict of its one read.
379+
const assets = document.assets.filter((a) => a.originalPath === videoPath);
380+
if (assets.length === 0) return [];
381+
const load = await readCursor(cursor, assets[0].id, videoPath);
382+
for (const asset of assets) telemetry[asset.id] = load.status;
382383
// The sidecar's samples, read as the renderer's `getTelemetry` reads them.
383384
return load.status === "ok" ? (load.samples as CursorTelemetryPoint[]) : [];
384385
});

0 commit comments

Comments
 (0)