diff --git a/src/telemetry/tool_call_metrics.json b/src/telemetry/tool_call_metrics.json index 14d8c13bf..f04bf0f9d 100644 --- a/src/telemetry/tool_call_metrics.json +++ b/src/telemetry/tool_call_metrics.json @@ -419,6 +419,11 @@ "args": [ { "name": "path_length", + "argType": "number", + "isDeprecated": true + }, + { + "name": "file_path_length", "argType": "number" } ] diff --git a/src/tools/screencast.ts b/src/tools/screencast.ts index 0523556a1..ad7130455 100644 --- a/src/tools/screencast.ts +++ b/src/tools/screencast.ts @@ -9,7 +9,7 @@ import os from 'node:os'; import path from 'node:path'; import {zod} from '../third_party/index.js'; -import type {ScreenRecorder} from '../third_party/index.js'; +import type {ScreenRecorder, VideoFormat} from '../third_party/index.js'; import {ensureExtension} from '../utils/files.js'; import {ToolCategory} from './categories.js'; @@ -20,10 +20,11 @@ async function generateTempFilePath(): Promise { return path.join(dir, `screencast.mp4`); } +const supportedExtensions: Array<`.${string}`> = ['.webm', '.mp4']; + export const startScreencast = definePageTool(args => ({ name: 'screencast_start', - description: - 'Starts recording a screencast (video) of the selected page in mp4 format.', + description: `Starts recording a screencast (video) of the selected page in specified format.`, annotations: { category: ToolCategory.DEBUGGING, readOnlyHint: false, @@ -31,11 +32,11 @@ export const startScreencast = definePageTool(args => ({ conditions: ['screencast'], }, schema: { - path: zod + filePath: zod .string() .optional() .describe( - 'Output path. Uses mkdtemp to generate a unique path if not provided.', + `Output file path (${supportedExtensions.join(',')} are supported). Uses mkdtemp to generate a unique path if not provided.`, ), }, handler: async (request, response, context) => { @@ -46,16 +47,30 @@ export const startScreencast = definePageTool(args => ({ return; } - const filePath = request.params.path ?? (await generateTempFilePath()); - const resolvedPath = ensureExtension(path.resolve(filePath), '.mp4'); + const filePath = request.params.filePath ?? (await generateTempFilePath()); + let enforcedExtension = '.mp4' as `.${string}`; + let format: VideoFormat = 'mp4'; + + for (const supportedExtension of supportedExtensions) { + if (filePath.endsWith(supportedExtension)) { + enforcedExtension = supportedExtension; + format = supportedExtension.substring(1) as VideoFormat; + break; + } + } + + const resolvedPath = ensureExtension( + path.resolve(filePath), + enforcedExtension, + ) as `${string}.webm`; const page = request.page; let recorder: ScreenRecorder; try { recorder = await page.pptrPage.screencast({ - path: resolvedPath as `${string}.mp4`, - format: 'mp4' as const, + path: resolvedPath, + format: format, ffmpegPath: args?.experimentalFfmpegPath, }); } catch (err) { diff --git a/tests/tools/screencast.test.ts b/tests/tools/screencast.test.ts index b9250889e..d60ec7db1 100644 --- a/tests/tools/screencast.test.ts +++ b/tests/tools/screencast.test.ts @@ -35,7 +35,7 @@ describe('screencast', () => { await startScreencast().handler( { - params: {path: '/tmp/test-recording.mp4'}, + params: {filePath: '/tmp/test-recording.mp4'}, page: context.getSelectedMcpPage(), }, response, @@ -113,7 +113,7 @@ describe('screencast', () => { await assert.rejects( startScreencast().handler( { - params: {path: '/tmp/test.mp4'}, + params: {filePath: '/tmp/test.mp4'}, page: context.getSelectedMcpPage(), }, response,