Kimi K2.7 Code natively integrates MoonViT vision/video embeddings and autonomously invokes local ffmpeg tools to slice video intervals and ingest Base64 multimodal return blocks inside iterative agent loops.
Suitable tasks: UI animation review, video bug replication, screencast-to-code generation, and temporal visual reasoning.
Unsuitable tasks: Raw video files exceeding FHD (1920x1080) resolution without compression, non-thinking mode API calls.
Applicable model versions: kimi-k2.7-code.
Applicable clients/APIs: OpenAI Python SDK (openai>=1.0), Kimi Official API (https://api.moonshot.ai/v1).
Recommended inference parameters: tool_choice="auto", video resolution $\le$ FHD, request body $\le$ 100MB.
import base64
import json
import os
import subprocess
import tempfile
from pathlib import Path
from openai import OpenAI
tools = [{
"type": "function",
"function": {
"name": "watch_video_clip",
"description": "Watch a video file or a sub-clip of it. If start_time and end_time are not provided, the entire video will be returned.",
"parameters": {
"type": "object",
"properties": {
"path": {
"type": "string",
"description": "The path to the video file to watch"
},
"start_time": {
"type": "number",
"description": "The start time of the clip in seconds (optional, defaults to 0)"
},
"end_time": {
"type": "number",
"description": "The end time of the clip in seconds (optional, defaults to end of video)"
}
},
"required": ["path"]
}
}
}]
def watch_video_clip(path: str, start_time: float | None = None, end_time: float | None = None) -> list[dict]:
video_path = Path(path)
if not video_path.exists():
raise FileNotFoundError(f"Video file not found: {path}")
if start_time is None and end_time is None:
with open(path, "rb") as f:
video_base64 = base64.b64encode(f.read()).decode("utf-8")
return [
{"type": "video_url", "video_url": {"url": f"data:video/mp4;base64,{video_base64}"}},
{"type": "text", "text": f"Full video: {video_path.name}"}
]
probe = subprocess.run(
["ffprobe", "-v", "quiet", "-print_format", "json", "-show_format", path],
capture_output=True, text=True
)
duration = float(json.loads(probe.stdout)["format"]["duration"])
start_time = start_time or 0
end_time = end_time or duration
clip_duration = end_time - start_time
with tempfile.NamedTemporaryFile(suffix=".mp4", delete=False) as tmp:
tmp_path = tmp.name
try:
subprocess.run([
"ffmpeg", "-y", "-ss", str(start_time), "-i", path,
"-t", str(clip_duration), "-c:v", "libx264", "-c:a", "aac",
"-preset", "fast", "-crf", "23", "-movflags", "+faststart",
"-loglevel", "error", tmp_path
], check=True)
with open(tmp_path, "rb") as f:
video_base64 = base64.b64encode(f.read()).decode("utf-8")
return [
{"type": "video_url", "video_url": {"url": f"data:video/mp4;base64,{video_base64}"}},
{"type": "text", "text": f"Clip from {video_path.name}: {start_time}s - {end_time}s"}
]
finally:
if os.path.exists(tmp_path):
os.unlink(tmp_path)
client = OpenAI(
api_key=os.environ.get("MOONSHOT_API_KEY"),
base_url="https://api.moonshot.ai/v1"
)
def agent_loop(user_message: str):
messages = [
{"role": "system", "content": "You are a video analysis assistant. Use watch_video_clip to examine specific portions of videos."},
{"role": "user", "content": user_message}
]
while True:
response = client.chat.completions.create(
model="kimi-k2.7-code",
messages=messages,
tools=tools,
tool_choice="auto"
)
message = response.choices[0].message
messages.append(message.model_dump())
if not message.tool_calls:
return message.content
for tool_call in message.tool_calls:
if tool_call.function.name == "watch_video_clip":
args = json.loads(tool_call.function.arguments)
result = watch_video_clip(
path=args["path"],
start_time=args.get("start_time"),
end_time=args.get("end_time")
)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": result
})MoonViT 400M parameters vision encoder handles joint spatial-temporal embeddings.
Formats: MP4, MOV, WebM, AVI (max FHD 1080p).
100MB body limit; URL-based images not supported (requires Base64 or File Upload API).
Kimi K2.7 Code