"use strict"; import type { ExtensionAPI } from "@earendil-works/pi-coding-agent"; import { Type } from "typebox"; import { getConfig } from "../config"; import { processVideo } from "../media"; import { visionCompletion } from "../client"; import { VIDEO_ANALYSIS } from "../prompts"; import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, truncateHead, } from "@earendil-works/pi-coding-agent"; export function registerVideoAnalysisTool(pi: ExtensionAPI) { pi.registerTool({ name: "video_analysis", label: "Video Analysis", description: "Analyze video content (MP4, MOV, M4V, AVI, WebM, WMV up to 8MB). Identifies scenes, actions, events, and key information by sending video frames to GLM-4.6V for visual understanding. Supports local files and HTTP(S) URLs.", promptSnippet: "Analyze video content — identify scenes, actions, events, and key moments", promptGuidelines: [ "Use video_analysis when the user provides a video file and wants to understand its content. Supported formats: mp4, mov, m4v, avi, webm, wmv. Max local file size: 8MB. Use HTTP(S) URLs for larger videos.", ], parameters: Type.Object({ videoPath: Type.String({ description: "Path to the video file (relative to cwd, supports @ prefix) or HTTP(S) URL. Supported: mp4, mov, m4v, avi, webm, wmv (max 8MB local).", }), prompt: Type.String({ description: "What should the AI analyze about this video? (e.g., 'Describe what happens', 'Identify all UI interactions shown', 'What is the error in this screen recording?').", }), }), async execute(_toolCallId, params, signal, onUpdate, ctx) { const config = getConfig(); onUpdate?.({ content: [{ type: "text", text: "正在调用 GLM-4.6V 分析视频..." }], }); const video = processVideo(params.videoPath, ctx.cwd, config.maxVideoSizeMB); const result = await visionCompletion( config, VIDEO_ANALYSIS, [video], params.prompt, signal ); const truncated = truncateHead(result, { maxLines: DEFAULT_MAX_LINES, maxBytes: DEFAULT_MAX_BYTES, }); let text = truncated.content; if (truncated.truncated) { text += `\n\n[输出已截断: ${truncated.outputLines}/${truncated.totalLines} 行]`; } return { content: [{ type: "text", text }], details: { raw: result }, }; }, }); }