11import click
2+ from prich .constants import RESERVED_RUN_TEMPLATE_CLI_OPTIONS
3+ from prich .models .template import TemplateModel
24from prich .core .loaders import load_global_config , load_local_config , load_merged_config , load_templates
3- from prich .core .engine import create_dynamic_command
5+ from prich .core .engine import run_template
46from prich .core .state import _loaded_templates
5- from prich .core .utils import should_use_global_only , should_use_local_only
7+ from prich .core .utils import should_use_global_only , should_use_local_only , is_verbose , console_print
68
79
810class DynamicCommandGroup (click .Group ):
@@ -31,4 +33,66 @@ def _load_dynamic_commands(self, ctx):
3133 except Exception as e :
3234 raise click .ClickException (f"Failed to load dynamic parameters: { e } " )
3335
34- self ._commands_loaded = True
36+ self ._commands_loaded = True
37+
38+
39+ def get_variable_type (variable_type : str ) -> click .types :
40+ type_mapping = {"str" : click .STRING , "int" : click .INT , "bool" : click .BOOL , "path" : click .Path }
41+ return type_mapping .get (variable_type .lower (), None )
42+
43+
44+ def create_dynamic_command (config , template : TemplateModel ) -> click .Command :
45+ options = []
46+ for arg in template .variables if template .variables else []:
47+ arg_name = arg .name
48+ arg_type = get_variable_type (arg .type )
49+ help_text = arg .description or f"{ arg_name } option"
50+ cli_option = arg .cli_option or f"--{ arg_name } "
51+ if cli_option in RESERVED_RUN_TEMPLATE_CLI_OPTIONS :
52+ raise click .ClickException (f"{ arg_name } cli option uses a reserved option name: { cli_option } " )
53+
54+ if arg_type == click .BOOL :
55+ options .append (click .Option ([cli_option ], is_flag = True , default = arg .default or False , show_default = True ,
56+ help = help_text ))
57+ elif arg_type :
58+ options .append (
59+ click .Option ([cli_option ], type = arg_type , default = arg .default , required = arg .required , show_default = True ,
60+ help = help_text ))
61+ elif arg .type .startswith ("list[" ):
62+ list_type = get_variable_type (arg .type .split ('[' )[1 ][:- 1 ])
63+ if not list_type :
64+ raise click .ClickException (f"Failed to parse list type for { arg .name } " )
65+ options .append (
66+ click .Option ([cli_option ], type = list_type , multiple = True , default = arg .default , required = arg .required ,
67+ show_default = True , help = help_text ))
68+ else :
69+ raise click .ClickException (f"Unsupported variable type: { arg .type } " )
70+
71+ options .extend ([
72+ click .Option (["-g" , "--global" , "global_only" ], is_flag = True , default = False ,
73+ help = "Use global config and template" ),
74+ click .Option (["-l" , "--local" , "local_only" ], is_flag = True , default = False ,
75+ help = "Use local config and template" ),
76+ click .Option (["-o" , "--output" ], type = click .Path (), default = None , show_default = True ,
77+ help = "Save final output to file" ),
78+ click .Option (["-p" , "--provider" ], type = click .Choice (config .providers .keys ()), show_default = True ,
79+ help = "Override LLM provider" ),
80+ click .Option (["-v" , "--verbose" ], is_flag = True , default = False , help = "Verbose mode" ),
81+ click .Option (["-q" , "--quiet" ], is_flag = True , default = False , help = "Suppress all output" ),
82+ click .Option (["-f" , "--only-final-output" ], is_flag = True , default = False ,
83+ help = "Suppress output and show only the last step output" )
84+ ])
85+
86+ @click .pass_context
87+ def dynamic_command (ctx , ** kwargs ):
88+ if is_verbose ():
89+ console_print (
90+ f"[dim]Template: [green]{ template .name } [/green] ({ template .version } ), { template .source .value } , args: { ', ' .join ([f'{ k } ={ v } ' for k , v in kwargs .items () if v ])} [/dim]" )
91+ console_print (f"[dim]{ template .description } [/dim]" )
92+ else :
93+ console_print (f"[dim][green]{ template .name } [/green] ({ template .version } ), { template .source .value } [/dim]" )
94+ run_template (template .id , ** kwargs )
95+
96+ return click .Command (name = template .id , callback = dynamic_command , params = options ,
97+ help = f"{ template .description if template .description else '' } " ,
98+ epilog = f"{ template .name } (ver: { template .version } , { template .source .value } )" )
0 commit comments