ostruct-cli 0.7.2__py3-none-any.whl → 0.8.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. ostruct/cli/__init__.py +21 -3
  2. ostruct/cli/base_errors.py +1 -1
  3. ostruct/cli/cli.py +66 -1983
  4. ostruct/cli/click_options.py +460 -28
  5. ostruct/cli/code_interpreter.py +238 -0
  6. ostruct/cli/commands/__init__.py +32 -0
  7. ostruct/cli/commands/list_models.py +128 -0
  8. ostruct/cli/commands/quick_ref.py +50 -0
  9. ostruct/cli/commands/run.py +137 -0
  10. ostruct/cli/commands/update_registry.py +71 -0
  11. ostruct/cli/config.py +277 -0
  12. ostruct/cli/cost_estimation.py +134 -0
  13. ostruct/cli/errors.py +310 -6
  14. ostruct/cli/exit_codes.py +1 -0
  15. ostruct/cli/explicit_file_processor.py +548 -0
  16. ostruct/cli/field_utils.py +69 -0
  17. ostruct/cli/file_info.py +42 -9
  18. ostruct/cli/file_list.py +301 -102
  19. ostruct/cli/file_search.py +455 -0
  20. ostruct/cli/file_utils.py +47 -13
  21. ostruct/cli/mcp_integration.py +541 -0
  22. ostruct/cli/model_creation.py +150 -1
  23. ostruct/cli/model_validation.py +204 -0
  24. ostruct/cli/progress_reporting.py +398 -0
  25. ostruct/cli/registry_updates.py +14 -9
  26. ostruct/cli/runner.py +1418 -0
  27. ostruct/cli/schema_utils.py +113 -0
  28. ostruct/cli/services.py +626 -0
  29. ostruct/cli/template_debug.py +748 -0
  30. ostruct/cli/template_debug_help.py +162 -0
  31. ostruct/cli/template_env.py +15 -6
  32. ostruct/cli/template_filters.py +55 -3
  33. ostruct/cli/template_optimizer.py +474 -0
  34. ostruct/cli/template_processor.py +1080 -0
  35. ostruct/cli/template_rendering.py +69 -34
  36. ostruct/cli/token_validation.py +286 -0
  37. ostruct/cli/types.py +78 -0
  38. ostruct/cli/unattended_operation.py +269 -0
  39. ostruct/cli/validators.py +386 -3
  40. {ostruct_cli-0.7.2.dist-info → ostruct_cli-0.8.0.dist-info}/LICENSE +2 -0
  41. ostruct_cli-0.8.0.dist-info/METADATA +633 -0
  42. ostruct_cli-0.8.0.dist-info/RECORD +69 -0
  43. {ostruct_cli-0.7.2.dist-info → ostruct_cli-0.8.0.dist-info}/WHEEL +1 -1
  44. ostruct_cli-0.7.2.dist-info/METADATA +0 -370
  45. ostruct_cli-0.7.2.dist-info/RECORD +0 -45
  46. {ostruct_cli-0.7.2.dist-info → ostruct_cli-0.8.0.dist-info}/entry_points.txt +0 -0
@@ -47,6 +47,73 @@ def debug_options(f: Union[Command, Callable[..., Any]]) -> Command:
47
47
  help="Show detailed validation errors",
48
48
  )(cmd)
49
49
 
50
+ cmd = click.option(
51
+ "--debug",
52
+ is_flag=True,
53
+ help="🐛 Enable debug-level logging including template expansion",
54
+ )(cmd)
55
+
56
+ cmd = click.option(
57
+ "--show-templates",
58
+ is_flag=True,
59
+ help="📝 Show expanded templates before sending to API",
60
+ )(cmd)
61
+
62
+ cmd = click.option(
63
+ "--debug-templates",
64
+ is_flag=True,
65
+ help="🔍 Enable detailed template expansion debugging with step-by-step analysis",
66
+ )(cmd)
67
+
68
+ cmd = click.option(
69
+ "--show-context",
70
+ is_flag=True,
71
+ help="📋 Show template variable context summary",
72
+ )(cmd)
73
+
74
+ cmd = click.option(
75
+ "--show-context-detailed",
76
+ is_flag=True,
77
+ help="📋 Show detailed template variable context with content preview",
78
+ )(cmd)
79
+
80
+ cmd = click.option(
81
+ "--show-pre-optimization",
82
+ is_flag=True,
83
+ help="🔧 Show template content before optimization is applied",
84
+ )(cmd)
85
+
86
+ cmd = click.option(
87
+ "--show-optimization-diff",
88
+ is_flag=True,
89
+ help="🔄 Show template optimization changes (before/after comparison)",
90
+ )(cmd)
91
+
92
+ cmd = click.option(
93
+ "--no-optimization",
94
+ is_flag=True,
95
+ help="⚡ Skip template optimization entirely for debugging",
96
+ )(cmd)
97
+
98
+ cmd = click.option(
99
+ "--show-optimization-steps",
100
+ is_flag=True,
101
+ help="🔧 Show detailed optimization step tracking with before/after changes",
102
+ )(cmd)
103
+
104
+ cmd = click.option(
105
+ "--optimization-step-detail",
106
+ type=click.Choice(["summary", "detailed"]),
107
+ default="summary",
108
+ help="📊 Level of optimization step detail (summary shows overview, detailed shows full diffs)",
109
+ )(cmd)
110
+
111
+ cmd = click.option(
112
+ "--help-debug",
113
+ is_flag=True,
114
+ help="📚 Show comprehensive template debugging help and examples",
115
+ )(cmd)
116
+
50
117
  # Final cast to Command for return type
51
118
  return cast(Command, cmd)
52
119
 
@@ -63,8 +130,9 @@ def file_options(f: Union[Command, Callable[..., Any]]) -> Command:
63
130
  nargs=2,
64
131
  metavar="<NAME> <PATH>",
65
132
  callback=validate_name_path_pair,
66
- help="""Associate a file with a variable name. The file will be available in
67
- your template as the specified variable. You can specify this option multiple times.
133
+ help="""[LEGACY] Associate a file with a variable name for template access only.
134
+ The file will be available in your template as the specified variable.
135
+ For explicit tool routing, use -ft, -fc, or -fs instead.
68
136
  Example: -f code main.py -f test test_main.py""",
69
137
  shell_complete=click.Path(exists=True, file_okay=True, dir_okay=False),
70
138
  )(cmd)
@@ -77,12 +145,92 @@ def file_options(f: Union[Command, Callable[..., Any]]) -> Command:
77
145
  nargs=2,
78
146
  metavar="<NAME> <DIR>",
79
147
  callback=validate_name_path_pair,
80
- help="""Associate a directory with a variable name. All files in the directory
81
- will be available in your template. Use -R for recursive scanning.
148
+ help="""[LEGACY] Associate a directory with a variable name for template access only.
149
+ All files in the directory will be available in your template. Use -R for recursive scanning.
150
+ For explicit tool routing, use -dt, -dc, or -ds instead.
82
151
  Example: -d src ./src""",
83
152
  shell_complete=click.Path(exists=True, file_okay=False, dir_okay=True),
84
153
  )(cmd)
85
154
 
155
+ # Template files with auto-naming ONLY (single argument)
156
+ cmd = click.option(
157
+ "-ft",
158
+ "--file-for-template",
159
+ "template_files",
160
+ multiple=True,
161
+ type=click.Path(exists=True, file_okay=True, dir_okay=False),
162
+ help="""📄 [TEMPLATE] Files for template access only (auto-naming). These files will be available
163
+ in your template but will not be uploaded to any tools. Use for configuration files,
164
+ small data files, or any content you want to reference in templates.
165
+ Format: -ft path (auto-generates variable name from filename).
166
+ Access file content: {{ variable.content }} (not just {{ variable }})
167
+ Example: -ft config.yaml → config_yaml variable, use {{ config_yaml.content }}""",
168
+ shell_complete=click.Path(exists=True, file_okay=True, dir_okay=False),
169
+ )(cmd)
170
+
171
+ # Template files with two-argument alias syntax (explicit naming)
172
+ cmd = click.option(
173
+ "--fta",
174
+ "--file-for-template-alias",
175
+ "template_file_aliases",
176
+ multiple=True,
177
+ nargs=2,
178
+ metavar="<NAME> <PATH>",
179
+ callback=validate_name_path_pair,
180
+ help="""📄 [TEMPLATE] Files for template with custom aliases. Use this for reusable
181
+ templates where you need stable variable names independent of file paths.
182
+ Format: --fta name path (supports tab completion for paths).
183
+ Access file content: {{ name.content }} (not just {{ name }})
184
+ Example: --fta config_data config.yaml → use {{ config_data.content }}""",
185
+ shell_complete=click.Path(exists=True, file_okay=True, dir_okay=False),
186
+ )(cmd)
187
+
188
+ cmd = click.option(
189
+ "-dt",
190
+ "--dir-for-template",
191
+ "template_dirs",
192
+ multiple=True,
193
+ type=click.Path(exists=True, file_okay=False, dir_okay=True),
194
+ help="""📁 [TEMPLATE] Directories for template access only (auto-naming). All files will be available
195
+ in your template but will not be uploaded to any tools. Use for project configurations,
196
+ reference data, or any directory content you want accessible in templates.
197
+ Format: -dt path (auto-generates variable name from directory name).
198
+ Example: -dt ./config -dt ./data""",
199
+ shell_complete=click.Path(exists=True, file_okay=False, dir_okay=True),
200
+ )(cmd)
201
+
202
+ # Template directories with two-argument alias syntax (explicit naming)
203
+ cmd = click.option(
204
+ "--dta",
205
+ "--dir-for-template-alias",
206
+ "template_dir_aliases",
207
+ multiple=True,
208
+ nargs=2,
209
+ metavar="<NAME> <PATH>",
210
+ callback=validate_name_path_pair,
211
+ help="""📁 [TEMPLATE] Directories for template with custom aliases. Use this for reusable
212
+ templates where you need stable variable names independent of directory paths.
213
+ Format: --dta name path (supports tab completion for paths).
214
+ Example: --dta config_data ./settings --dta source_code ./src""",
215
+ shell_complete=click.Path(exists=True, file_okay=False, dir_okay=True),
216
+ )(cmd)
217
+
218
+ cmd = click.option(
219
+ "--file-for",
220
+ "tool_files",
221
+ nargs=2,
222
+ multiple=True,
223
+ metavar="TOOL PATH",
224
+ help="""🔄 [ADVANCED] Route files to specific tools. Use this for precise control
225
+ over which tools receive which files. Supports tab completion for both tool names
226
+ and file paths.
227
+ Format: --file-for TOOL PATH
228
+ Examples:
229
+ --file-for code-interpreter analysis.py
230
+ --file-for file-search docs.pdf
231
+ --file-for template config.yaml""",
232
+ )(cmd)
233
+
86
234
  cmd = click.option(
87
235
  "-p",
88
236
  "--pattern",
@@ -90,7 +238,7 @@ def file_options(f: Union[Command, Callable[..., Any]]) -> Command:
90
238
  multiple=True,
91
239
  nargs=2,
92
240
  metavar="<NAME> <PATTERN>",
93
- help="""Associate a glob pattern with a variable name. Matching files will be
241
+ help="""[LEGACY] Associate a glob pattern with a variable name. Matching files will be
94
242
  available in your template. Use -R for recursive matching.
95
243
  Example: -p logs '*.log'""",
96
244
  )(cmd)
@@ -143,7 +291,9 @@ def variable_options(f: Union[Command, Callable[..., Any]]) -> Command:
143
291
  multiple=True,
144
292
  metavar="name=value",
145
293
  callback=validate_variable,
146
- help="""Define a simple string variable. Format: name=value
294
+ help="""🏷️ [VARIABLES] Define a simple string variable for template substitution.
295
+ Variables are available in your template as {{ variable_name }}.
296
+ Format: name=value
147
297
  Example: -V debug=true -V env=prod""",
148
298
  )(cmd)
149
299
 
@@ -154,7 +304,9 @@ def variable_options(f: Union[Command, Callable[..., Any]]) -> Command:
154
304
  multiple=True,
155
305
  metavar='name=\'{"json":"value"}\'',
156
306
  callback=validate_json_variable,
157
- help="""Define a JSON variable. Format: name='{"key":"value"}'
307
+ help="""📋 [VARIABLES] Define a JSON variable for complex data structures.
308
+ JSON variables are parsed and available in templates as structured objects.
309
+ Format: name='{"key":"value"}'
158
310
  Example: -J config='{"env":"prod","debug":true}'""",
159
311
  )(cmd)
160
312
 
@@ -278,6 +430,12 @@ def api_options(f: Union[Command, Callable[..., Any]]) -> Command:
278
430
  """Add API-related CLI options."""
279
431
  cmd: Any = f if isinstance(f, Command) else f
280
432
 
433
+ cmd = click.option(
434
+ "--config",
435
+ type=click.Path(exists=True),
436
+ help="Configuration file path (default: ostruct.yaml)",
437
+ )(cmd)
438
+
281
439
  cmd = click.option(
282
440
  "--api-key",
283
441
  help="""OpenAI API key. If not provided, uses OPENAI_API_KEY
@@ -295,6 +453,278 @@ def api_options(f: Union[Command, Callable[..., Any]]) -> Command:
295
453
  return cast(Command, cmd)
296
454
 
297
455
 
456
+ def mcp_options(f: Union[Command, Callable[..., Any]]) -> Command:
457
+ """Add MCP (Model Context Protocol) server CLI options."""
458
+ cmd: Any = f if isinstance(f, Command) else f
459
+
460
+ cmd = click.option(
461
+ "--mcp-server",
462
+ "mcp_servers",
463
+ multiple=True,
464
+ help="""🔌 [MCP] Connect to Model Context Protocol server for extended capabilities.
465
+ MCP servers provide additional tools like web search, databases, APIs, etc.
466
+ Format: [label@]url
467
+ Example: --mcp-server deepwiki@https://mcp.deepwiki.com/sse""",
468
+ )(cmd)
469
+
470
+ cmd = click.option(
471
+ "--mcp-allowed-tools",
472
+ "mcp_allowed_tools",
473
+ multiple=True,
474
+ help="""Allowed tools per server. Format: server_label:tool1,tool2
475
+ Example: --mcp-allowed-tools deepwiki:search,summary""",
476
+ )(cmd)
477
+
478
+ cmd = click.option(
479
+ "--mcp-require-approval",
480
+ type=click.Choice(["always", "never"]),
481
+ default="never",
482
+ show_default=True,
483
+ help="""Approval level for MCP tool usage. CLI usage requires 'never'.""",
484
+ )(cmd)
485
+
486
+ cmd = click.option(
487
+ "--mcp-headers",
488
+ help="""JSON string of headers for MCP servers.
489
+ Example: --mcp-headers '{"Authorization": "Bearer token"}'""",
490
+ )(cmd)
491
+
492
+ return cast(Command, cmd)
493
+
494
+
495
+ def code_interpreter_options(f: Union[Command, Callable[..., Any]]) -> Command:
496
+ """Add Code Interpreter CLI options."""
497
+ cmd: Any = f if isinstance(f, Command) else f
498
+
499
+ # Code interpreter files with auto-naming ONLY (single argument)
500
+ cmd = click.option(
501
+ "-fc",
502
+ "--file-for-code-interpreter",
503
+ "code_interpreter_files",
504
+ multiple=True,
505
+ type=click.Path(exists=True, file_okay=True, dir_okay=False),
506
+ help="""💻 [CODE INTERPRETER] Files to upload for code execution and analysis (auto-naming).
507
+ Perfect for data files (CSV, JSON), code files (Python, R), or any files that
508
+ need computational processing. Files are uploaded to an isolated execution environment.
509
+ Format: -fc path (auto-generates variable name from filename).
510
+ Example: -fc data.csv → data_csv variable, -fc analysis.py → analysis_py variable""",
511
+ shell_complete=click.Path(exists=True, file_okay=True, dir_okay=False),
512
+ )(cmd)
513
+
514
+ # Code interpreter files with two-argument alias syntax (explicit naming)
515
+ cmd = click.option(
516
+ "--fca",
517
+ "--file-for-code-interpreter-alias",
518
+ "code_interpreter_file_aliases",
519
+ multiple=True,
520
+ nargs=2,
521
+ metavar="<NAME> <PATH>",
522
+ callback=validate_name_path_pair,
523
+ help="""💻 [CODE INTERPRETER] Files for code execution with custom aliases.
524
+ Format: --fca name path (supports tab completion for paths).
525
+ Example: --fca dataset src/data.csv --fca script analysis.py""",
526
+ shell_complete=click.Path(exists=True, file_okay=True, dir_okay=False),
527
+ )(cmd)
528
+
529
+ cmd = click.option(
530
+ "-dc",
531
+ "--dir-for-code-interpreter",
532
+ "code_interpreter_dirs",
533
+ multiple=True,
534
+ type=click.Path(exists=True, file_okay=False, dir_okay=True),
535
+ help="""📂 [CODE INTERPRETER] Directories to upload for code execution (auto-naming). All files
536
+ in the directory will be uploaded to the execution environment. Use for datasets,
537
+ code repositories, or any directory that needs computational processing.
538
+ Format: -dc path (auto-generates variable name from directory name).
539
+ Example: -dc ./data -dc ./scripts""",
540
+ shell_complete=click.Path(exists=True, file_okay=False, dir_okay=True),
541
+ )(cmd)
542
+
543
+ # Code interpreter directories with two-argument alias syntax (explicit naming)
544
+ cmd = click.option(
545
+ "--dca",
546
+ "--dir-for-code-interpreter-alias",
547
+ "code_interpreter_dir_aliases",
548
+ multiple=True,
549
+ nargs=2,
550
+ metavar="<NAME> <PATH>",
551
+ callback=validate_name_path_pair,
552
+ help="""📂 [CODE INTERPRETER] Directories for code execution with custom aliases.
553
+ Format: --dca name path (supports tab completion for paths).
554
+ Example: --dca dataset ./data --dca source_code ./src""",
555
+ shell_complete=click.Path(exists=True, file_okay=False, dir_okay=True),
556
+ )(cmd)
557
+
558
+ cmd = click.option(
559
+ "--code-interpreter-download-dir",
560
+ type=click.Path(file_okay=False, dir_okay=True),
561
+ default="./downloads",
562
+ show_default=True,
563
+ help="""Directory to save files generated by Code Interpreter.
564
+ Example: --code-interpreter-download-dir ./results""",
565
+ shell_complete=click.Path(file_okay=False, dir_okay=True),
566
+ )(cmd)
567
+
568
+ cmd = click.option(
569
+ "--code-interpreter-cleanup",
570
+ is_flag=True,
571
+ default=True,
572
+ show_default=True,
573
+ help="""Clean up uploaded files after execution to save storage quota.""",
574
+ )(cmd)
575
+
576
+ return cast(Command, cmd)
577
+
578
+
579
+ def file_search_options(f: Union[Command, Callable[..., Any]]) -> Command:
580
+ """Add File Search CLI options."""
581
+ cmd: Any = f if isinstance(f, Command) else f
582
+
583
+ # File search files with auto-naming ONLY (single argument)
584
+ cmd = click.option(
585
+ "-fs",
586
+ "--file-for-search",
587
+ "file_search_files",
588
+ multiple=True,
589
+ type=click.Path(exists=True, file_okay=True, dir_okay=False),
590
+ help="""🔍 [FILE SEARCH] Files to upload for semantic vector search (auto-naming). Perfect for
591
+ documents (PDF, TXT, MD), manuals, knowledge bases, or any text content you want to
592
+ search through. Files are processed into a searchable vector store.
593
+ Format: -fs path (auto-generates variable name from filename).
594
+ Example: -fs docs.pdf → docs_pdf variable, -fs manual.txt → manual_txt variable""",
595
+ shell_complete=click.Path(exists=True, file_okay=True, dir_okay=False),
596
+ )(cmd)
597
+
598
+ # File search files with two-argument alias syntax (explicit naming)
599
+ cmd = click.option(
600
+ "--fsa",
601
+ "--file-for-search-alias",
602
+ "file_search_file_aliases",
603
+ multiple=True,
604
+ nargs=2,
605
+ metavar="<NAME> <PATH>",
606
+ callback=validate_name_path_pair,
607
+ help="""🔍 [FILE SEARCH] Files for search with custom aliases.
608
+ Format: --fsa name path (supports tab completion for paths).
609
+ Example: --fsa manual src/docs.pdf --fsa knowledge base.txt""",
610
+ shell_complete=click.Path(exists=True, file_okay=True, dir_okay=False),
611
+ )(cmd)
612
+
613
+ cmd = click.option(
614
+ "-ds",
615
+ "--dir-for-search",
616
+ "file_search_dirs",
617
+ multiple=True,
618
+ type=click.Path(exists=True, file_okay=False, dir_okay=True),
619
+ help="""📁 [FILE SEARCH] Directories to upload for semantic search (auto-naming). All files in the
620
+ directory will be processed into a searchable vector store. Use for documentation
621
+ directories, knowledge bases, or any collection of searchable documents.
622
+ Format: -ds path (auto-generates variable name from directory name).
623
+ Example: -ds ./docs -ds ./manuals""",
624
+ shell_complete=click.Path(exists=True, file_okay=False, dir_okay=True),
625
+ )(cmd)
626
+
627
+ # File search directories with two-argument alias syntax (explicit naming)
628
+ cmd = click.option(
629
+ "--dsa",
630
+ "--dir-for-search-alias",
631
+ "file_search_dir_aliases",
632
+ multiple=True,
633
+ nargs=2,
634
+ metavar="<NAME> <PATH>",
635
+ callback=validate_name_path_pair,
636
+ help="""📁 [FILE SEARCH] Directories for search with custom aliases.
637
+ Format: --dsa name path (supports tab completion for paths).
638
+ Example: --dsa documentation ./docs --dsa knowledge_base ./manuals""",
639
+ shell_complete=click.Path(exists=True, file_okay=False, dir_okay=True),
640
+ )(cmd)
641
+
642
+ cmd = click.option(
643
+ "--file-search-vector-store-name",
644
+ default="ostruct_search",
645
+ show_default=True,
646
+ help="""Name for the vector store created for File Search.
647
+ Example: --file-search-vector-store-name project_docs""",
648
+ )(cmd)
649
+
650
+ cmd = click.option(
651
+ "--file-search-cleanup",
652
+ is_flag=True,
653
+ default=True,
654
+ show_default=True,
655
+ help="""Clean up uploaded files and vector stores after execution.""",
656
+ )(cmd)
657
+
658
+ cmd = click.option(
659
+ "--file-search-retry-count",
660
+ type=click.IntRange(1, 10),
661
+ default=3,
662
+ show_default=True,
663
+ help="""Number of retry attempts for File Search operations.
664
+ Higher values improve reliability for intermittent failures.""",
665
+ )(cmd)
666
+
667
+ cmd = click.option(
668
+ "--file-search-timeout",
669
+ type=click.FloatRange(10.0, 300.0),
670
+ default=60.0,
671
+ show_default=True,
672
+ help="""Timeout in seconds for vector store indexing.
673
+ Typically instant but may take longer for large files.""",
674
+ )(cmd)
675
+
676
+ return cast(Command, cmd)
677
+
678
+
679
+ def web_search_options(f: Union[Command, Callable[..., Any]]) -> Command:
680
+ """Add Web Search CLI options."""
681
+ cmd: Any = f if isinstance(f, Command) else f
682
+
683
+ cmd = click.option(
684
+ "--web-search",
685
+ is_flag=True,
686
+ help="""🌐 [WEB SEARCH] Enable OpenAI web search tool for up-to-date information.
687
+ Allows the model to search the web for current events, recent updates, and real-time data.
688
+ Note: Search queries may be sent to external services via OpenAI.""",
689
+ )(cmd)
690
+
691
+ cmd = click.option(
692
+ "--no-web-search",
693
+ is_flag=True,
694
+ help="""Explicitly disable web search even if enabled by default in configuration.""",
695
+ )(cmd)
696
+
697
+ cmd = click.option(
698
+ "--user-country",
699
+ type=str,
700
+ help="""🌐 [WEB SEARCH] Specify user country for geographically tailored search results.
701
+ Used to improve search relevance by location (e.g., 'US', 'UK', 'Germany').""",
702
+ )(cmd)
703
+
704
+ cmd = click.option(
705
+ "--user-city",
706
+ type=str,
707
+ help="""🌐 [WEB SEARCH] Specify user city for geographically tailored search results.
708
+ Used to improve search relevance by location (e.g., 'San Francisco', 'London').""",
709
+ )(cmd)
710
+
711
+ cmd = click.option(
712
+ "--user-region",
713
+ type=str,
714
+ help="""🌐 [WEB SEARCH] Specify user region/state for geographically tailored search results.
715
+ Used to improve search relevance by location (e.g., 'California', 'Bavaria').""",
716
+ )(cmd)
717
+
718
+ cmd = click.option(
719
+ "--search-context-size",
720
+ type=click.Choice(["low", "medium", "high"]),
721
+ help="""🌐 [WEB SEARCH] Control the amount of content retrieved from web pages.
722
+ 'low' retrieves minimal content, 'high' retrieves comprehensive content. Default: medium.""",
723
+ )(cmd)
724
+
725
+ return cast(Command, cmd)
726
+
727
+
298
728
  def debug_progress_options(f: Union[Command, Callable[..., Any]]) -> Command:
299
729
  """Add debugging and progress CLI options."""
300
730
  cmd: Any = f if isinstance(f, Command) else f
@@ -322,33 +752,35 @@ def debug_progress_options(f: Union[Command, Callable[..., Any]]) -> Command:
322
752
  help="Debug OpenAI streaming process",
323
753
  )(cmd)
324
754
 
755
+ cmd = click.option(
756
+ "--timeout",
757
+ type=int,
758
+ default=3600,
759
+ help="Operation timeout in seconds (default: 3600 = 1 hour)",
760
+ )(cmd)
761
+
325
762
  return cast(Command, cmd)
326
763
 
327
764
 
328
765
  def all_options(f: Union[Command, Callable[..., Any]]) -> Command:
329
- """Add all CLI options.
766
+ """Apply all CLI options to a command."""
767
+ cmd: Any = f if isinstance(f, Command) else f
330
768
 
331
- Args:
332
- f: Function to decorate
769
+ # Apply option groups in order
770
+ cmd = file_options(cmd)
771
+ cmd = variable_options(cmd)
772
+ cmd = model_options(cmd)
773
+ cmd = system_prompt_options(cmd)
774
+ cmd = output_options(cmd)
775
+ cmd = api_options(cmd)
776
+ cmd = mcp_options(cmd)
777
+ cmd = code_interpreter_options(cmd)
778
+ cmd = file_search_options(cmd)
779
+ cmd = web_search_options(cmd)
780
+ cmd = debug_options(cmd)
781
+ cmd = debug_progress_options(cmd)
333
782
 
334
- Returns:
335
- Decorated function
336
- """
337
- decorators = [
338
- model_options, # Model selection and parameters first
339
- system_prompt_options, # System prompt configuration
340
- file_options, # File and directory handling
341
- variable_options, # Variable definitions
342
- output_options, # Output control
343
- api_options, # API configuration
344
- debug_options, # Debug settings
345
- debug_progress_options, # Progress and logging
346
- ]
347
-
348
- for decorator in decorators:
349
- f = decorator(f)
350
-
351
- return cast(Command, f)
783
+ return cast(Command, cmd)
352
784
 
353
785
 
354
786
  def create_click_command() -> CommandDecorator: