PlanOpticon

feat(cli): add --output-format json and --templates-dir to analyze command

lmata 2026-03-07 22:10 trunk
Commit 5e5d3c2161f14858d3beb94f461258a4bc5c294428b03a63b693deb601e7a114
--- video_processor/cli/commands.py
+++ video_processor/cli/commands.py
@@ -92,10 +92,22 @@
9292
default="auto",
9393
help="API provider",
9494
)
9595
@click.option("--vision-model", type=str, default=None, help="Override model for vision tasks")
9696
@click.option("--chat-model", type=str, default=None, help="Override model for LLM/chat tasks")
97
+@click.option(
98
+ "--output-format",
99
+ type=click.Choice(["default", "json"]),
100
+ default="default",
101
+ help="Output format: default (files + summary) or json (structured JSON to stdout)",
102
+)
103
+@click.option(
104
+ "--templates-dir",
105
+ type=click.Path(exists=True),
106
+ default=None,
107
+ help="Directory with custom prompt template .txt files",
108
+)
97109
@click.pass_context
98110
def analyze(
99111
ctx,
100112
input,
101113
output,
@@ -107,10 +119,12 @@
107119
periodic_capture,
108120
title,
109121
provider,
110122
vision_model,
111123
chat_model,
124
+ output_format,
125
+ templates_dir,
112126
):
113127
"""Analyze a single video and extract structured knowledge."""
114128
from video_processor.pipeline import process_single_video
115129
from video_processor.providers.manager import ProviderManager
116130
@@ -121,12 +135,17 @@
121135
vision_model=vision_model,
122136
chat_model=chat_model,
123137
provider=prov,
124138
)
125139
140
+ if templates_dir:
141
+ from video_processor.utils.prompt_templates import PromptTemplate
142
+
143
+ pm.prompt_templates = PromptTemplate(templates_dir=templates_dir)
144
+
126145
try:
127
- process_single_video(
146
+ manifest = process_single_video(
128147
input_path=input,
129148
output_dir=output,
130149
provider_manager=pm,
131150
depth=depth,
132151
focus_areas=focus_areas,
@@ -134,15 +153,21 @@
134153
change_threshold=change_threshold,
135154
periodic_capture_seconds=periodic_capture,
136155
use_gpu=use_gpu,
137156
title=title,
138157
)
139
- click.echo(pm.usage.format_summary())
140
- click.echo(f"\n Results: {output}/manifest.json")
158
+ if output_format == "json":
159
+ click.echo(json.dumps(manifest.model_dump(), indent=2, default=str))
160
+ else:
161
+ click.echo(pm.usage.format_summary())
162
+ click.echo(f"\n Results: {output}/manifest.json")
141163
except Exception as e:
142164
logging.error(f"Error: {e}")
143
- click.echo(pm.usage.format_summary())
165
+ if output_format == "json":
166
+ click.echo(json.dumps({"error": str(e)}))
167
+ else:
168
+ click.echo(pm.usage.format_summary())
144169
if ctx.obj["verbose"]:
145170
import traceback
146171
147172
traceback.print_exc()
148173
sys.exit(1)
149174
--- video_processor/cli/commands.py
+++ video_processor/cli/commands.py
@@ -92,10 +92,22 @@
92 default="auto",
93 help="API provider",
94 )
95 @click.option("--vision-model", type=str, default=None, help="Override model for vision tasks")
96 @click.option("--chat-model", type=str, default=None, help="Override model for LLM/chat tasks")
 
 
 
 
 
 
 
 
 
 
 
 
97 @click.pass_context
98 def analyze(
99 ctx,
100 input,
101 output,
@@ -107,10 +119,12 @@
107 periodic_capture,
108 title,
109 provider,
110 vision_model,
111 chat_model,
 
 
112 ):
113 """Analyze a single video and extract structured knowledge."""
114 from video_processor.pipeline import process_single_video
115 from video_processor.providers.manager import ProviderManager
116
@@ -121,12 +135,17 @@
121 vision_model=vision_model,
122 chat_model=chat_model,
123 provider=prov,
124 )
125
 
 
 
 
 
126 try:
127 process_single_video(
128 input_path=input,
129 output_dir=output,
130 provider_manager=pm,
131 depth=depth,
132 focus_areas=focus_areas,
@@ -134,15 +153,21 @@
134 change_threshold=change_threshold,
135 periodic_capture_seconds=periodic_capture,
136 use_gpu=use_gpu,
137 title=title,
138 )
139 click.echo(pm.usage.format_summary())
140 click.echo(f"\n Results: {output}/manifest.json")
 
 
 
141 except Exception as e:
142 logging.error(f"Error: {e}")
143 click.echo(pm.usage.format_summary())
 
 
 
144 if ctx.obj["verbose"]:
145 import traceback
146
147 traceback.print_exc()
148 sys.exit(1)
149
--- video_processor/cli/commands.py
+++ video_processor/cli/commands.py
@@ -92,10 +92,22 @@
92 default="auto",
93 help="API provider",
94 )
95 @click.option("--vision-model", type=str, default=None, help="Override model for vision tasks")
96 @click.option("--chat-model", type=str, default=None, help="Override model for LLM/chat tasks")
97 @click.option(
98 "--output-format",
99 type=click.Choice(["default", "json"]),
100 default="default",
101 help="Output format: default (files + summary) or json (structured JSON to stdout)",
102 )
103 @click.option(
104 "--templates-dir",
105 type=click.Path(exists=True),
106 default=None,
107 help="Directory with custom prompt template .txt files",
108 )
109 @click.pass_context
110 def analyze(
111 ctx,
112 input,
113 output,
@@ -107,10 +119,12 @@
119 periodic_capture,
120 title,
121 provider,
122 vision_model,
123 chat_model,
124 output_format,
125 templates_dir,
126 ):
127 """Analyze a single video and extract structured knowledge."""
128 from video_processor.pipeline import process_single_video
129 from video_processor.providers.manager import ProviderManager
130
@@ -121,12 +135,17 @@
135 vision_model=vision_model,
136 chat_model=chat_model,
137 provider=prov,
138 )
139
140 if templates_dir:
141 from video_processor.utils.prompt_templates import PromptTemplate
142
143 pm.prompt_templates = PromptTemplate(templates_dir=templates_dir)
144
145 try:
146 manifest = process_single_video(
147 input_path=input,
148 output_dir=output,
149 provider_manager=pm,
150 depth=depth,
151 focus_areas=focus_areas,
@@ -134,15 +153,21 @@
153 change_threshold=change_threshold,
154 periodic_capture_seconds=periodic_capture,
155 use_gpu=use_gpu,
156 title=title,
157 )
158 if output_format == "json":
159 click.echo(json.dumps(manifest.model_dump(), indent=2, default=str))
160 else:
161 click.echo(pm.usage.format_summary())
162 click.echo(f"\n Results: {output}/manifest.json")
163 except Exception as e:
164 logging.error(f"Error: {e}")
165 if output_format == "json":
166 click.echo(json.dumps({"error": str(e)}))
167 else:
168 click.echo(pm.usage.format_summary())
169 if ctx.obj["verbose"]:
170 import traceback
171
172 traceback.print_exc()
173 sys.exit(1)
174

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button