Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cutagent/py.typed
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

118 changes: 118 additions & 0 deletions cutagent/tools.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
"""AI tool definitions and JSON Schemas for CutAgent."""

import json
from typing import Any


def get_tool_schema(tool_name: str) -> dict[str, Any]:
"""Return the JSON schema tool definition for a given tool.

Available tools:
- cutagent_capabilities
- cutagent_probe
- cutagent_summarize
- cutagent_validate
- cutagent_execute
"""
schemas = {
"cutagent_capabilities": {
"type": "function",
"function": {
"name": "cutagent_capabilities",
"description": "Discover all available video editing capabilities, operations, and the exact JSON schema for the Edit Decision List (EDL). Call this first to understand how to use CutAgent.",
"parameters": {
"type": "object",
"properties": {},
"required": [],
},
},
},
"cutagent_probe": {
"type": "function",
"function": {
"name": "cutagent_probe",
"description": "Probe a media file for metadata, including duration, resolution, codecs, and streams.",
"parameters": {
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "Path to the media file",
},
},
"required": ["file"],
},
},
},
"cutagent_summarize": {
"type": "function",
"function": {
"name": "cutagent_summarize",
"description": "Build a full content summary including scene boundaries, silence gaps, and suggested cut points.",
"parameters": {
"type": "object",
"properties": {
"file": {
"type": "string",
"description": "Path to the media file",
},
"scene_threshold": {
"type": "number",
"description": "Scene detection threshold (default 0.3)",
"default": 0.3,
},
},
"required": ["file"],
},
},
},
"cutagent_validate": {
"type": "function",
"function": {
"name": "cutagent_validate",
"description": "Validate an Edit Decision List (EDL) without executing it. Always run this before execute to catch errors early.",
"parameters": {
"type": "object",
"properties": {
"edl_json": {
"type": "string",
"description": "The full EDL JSON string to validate",
},
},
"required": ["edl_json"],
},
},
},
"cutagent_execute": {
"type": "function",
"function": {
"name": "cutagent_execute",
"description": "Execute an Edit Decision List (EDL) to perform the actual video editing operations.",
"parameters": {
"type": "object",
"properties": {
"edl_json": {
"type": "string",
"description": "The full EDL JSON string to execute",
},
},
"required": ["edl_json"],
},
},
},
}

if tool_name not in schemas:
raise ValueError(f"Unknown tool: {tool_name}")

return schemas[tool_name]

def dump_all_schemas() -> str:
"""Return a JSON array of all tool definitions for easy ingestion by AI agents."""
return json.dumps([
get_tool_schema("cutagent_capabilities"),
get_tool_schema("cutagent_probe"),
get_tool_schema("cutagent_summarize"),
get_tool_schema("cutagent_validate"),
get_tool_schema("cutagent_execute"),
], indent=2)
4 changes: 2 additions & 2 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ def _use_drawtext_ffmpeg_cli():

def _run_cli(*args: str, input_text: Optional[str] = None) -> subprocess.CompletedProcess[str]:
"""Run cutagent CLI as a subprocess and return the result."""
# Using uv run to make sure it picks up the virtual environment
cmd = ["uv", "run", "python", "-m", "cutagent"] + list(args)
import sys
cmd = [sys.executable, "-m", "cutagent"] + list(args)
return subprocess.run(
cmd,
capture_output=True,
Expand Down
Loading