Skip to content

Commit 2f847ef

Browse files
committed
fix(agent): preserve zoom transition warnings in filler cuts
1 parent 9938956 commit 2f847ef

3 files changed

Lines changed: 22 additions & 1 deletion

File tree

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2415,6 +2415,25 @@ describe("removeFillerWords", () => {
24152415
expect(next.timeline.trimRanges).toHaveLength(before.timeline.trimRanges.length + 1);
24162416
});
24172417

2418+
it("preserves addTrim warnings when removing a filler cuts a zoom transition", () => {
2419+
const before = repeatedWordDocument();
2420+
before.timeline.trimRanges = [];
2421+
const zoomed = run(before, "addZoom", { startSec: 2, endSec: 3, depth: 3 }).document;
2422+
expect(zoomed).toBeDefined();
2423+
if (!zoomed) throw new Error("Zoom fixture failed");
2424+
const directTrim = run(zoomed, "addTrim", {
2425+
assetId: "asset_1",
2426+
clipId: "clip_1",
2427+
startSec: 1,
2428+
endSec: 1.2,
2429+
});
2430+
const expected = JSON.parse(directTrim.resultJson).cutTransitions;
2431+
expect(expected.length).toBeGreaterThan(0);
2432+
const removed = run(zoomed, "removeFillerWords", { assetId: "asset_1", wordIds: ["filler"] });
2433+
expect(removed.ok).toBe(true);
2434+
expect(JSON.parse(removed.resultJson).cutTransitions).toEqual(expected);
2435+
});
2436+
24182437
it("refuses an invalid ID atomically, including when another ID is valid", () => {
24192438
const before = repeatedWordDocument();
24202439
const result = run(before, "removeFillerWords", { wordIds: ["filler", "missing"] });

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,7 @@ export function executeAgentTool(
16371637
requested: wordIds.length,
16381638
removedCount: removed.length,
16391639
removed,
1640+
...cutTransitionsReport(document, current),
16401641
}),
16411642
summary: `removed ${removed.length} filler word${removed.length === 1 ? "" : "s"}`,
16421643
};

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,8 @@ export const TOOL_DESCRIPTIONS: Record<string, string> = {
162162
setWordText:
163163
"Correct ONE word's text, by the id getTranscriptWords returns. This changes the TRANSCRIPT and nothing else: the captions follow it, the film is untouched and no audio is cut. Use it when the transcriber misheard something — a name, a technical term — and the user asks for it to read correctly. Passing an empty string BLANKS the word: it keeps its place in the media but leaves the captions, which is how a junk token like \"(inaudible)\" is removed without cutting the speech around it. Writing the transcriber's own text back clears the correction. This is NOT how you make a spoken word go away — that removes only the label and leaves the film saying it; use addTrim, which cuts the audio with it.",
164164
removeFillerWords:
165-
"Remove only the spoken filler-word occurrences selected by `wordIds` from getTranscriptWords. Pass the same `assetId` as that read: word IDs are numbered independently in each asset. Omit assetId only when the IDs are unique across all transcripts. Use ONLY when the user explicitly asks for filler-word cleanup. Read words in context and choose IDs yourself; the executor does not classify speech or remove every matching text. It resolves each ID to one recorded asset, valid source timestamps, and exactly one fully covering clip, then adds non-destructive trims. If any ID or target is invalid or ambiguous, nothing changes. The result lists each word and the ACTUAL trim span (which addTrim may shape), asset, clip and trim ID; report only those results.",
165+
"Remove only the spoken filler-word occurrences selected by `wordIds` from getTranscriptWords. Pass the same `assetId` as that read: word IDs are numbered independently in each asset. Omit assetId only when the IDs are unique across all transcripts. Use ONLY when the user explicitly asks for filler-word cleanup. Read words in context and choose IDs yourself; the executor does not classify speech or remove every matching text. It resolves each ID to one recorded asset, valid source timestamps, and exactly one fully covering clip, then adds non-destructive trims. If any ID or target is invalid or ambiguous, nothing changes. The result lists each word and the ACTUAL trim span (which addTrim may shape), asset, clip and trim ID; report only those results. " +
166+
CUT_TRANSITIONS_RESULT,
166167
addTrim: `Add ONE trim range: a cut of a span inside a clip (this source-time span will not be played or exported) that does NOT split the clip. Times are in seconds of the asset's source time. This is the preferred (and for 'remove silences' requests, the only) way to handle silences; it preserves the user's placed clips and only adds a cut. When you have several cuts to make, use addTrims and send them together — this one is for a single cut or a later correction. A cut belongs to ONE clip: \`clipId\` is inferred when a single clip covers the range, but when several clips draw on the same asset over it the call FAILS and lists them — pass the \`clipId\` you mean (ids come from getCurrentDocument). ${ZOOM_TRANSITIONS_NOTE} ${CUT_TRANSITIONS_RESULT}`,
167168
addTrims: `Add MANY trim ranges in one call: \`ranges\` is a list, each entry taking exactly the fields addTrim takes. Use this whenever you have more than one cut to make — 'remove the silences' on a half-hour recording is hundreds of cuts, and sending them one at a time costs one round trip each. Each range stands or falls ALONE: one that cannot be placed is refused by itself and listed in \`refused\` with its index and the reason, while every other range is still applied. Nothing is rolled back, so a single bad bound never costs you the rest. The result leads with requested / appliedCount / refusedCount so you can see a partial outcome without re-reading the document — report what was refused rather than claiming the whole list landed. ${ZOOM_TRANSITIONS_NOTE} Each applied entry carries the same \`cutTransitions\` warning addTrim reports.`,
168169
setTrim: `Move or resize an existing trim range by id. Times are source-time seconds. The cut follows to whichever clip the new range lands in, when that clip is unambiguous. ${ZOOM_TRANSITIONS_NOTE} ${CUT_TRANSITIONS_RESULT}`,

0 commit comments

Comments
 (0)