lc/cli/definitions.rs
1//! CLI definitions and command structures
2//! This file contains all the CLI struct and enum definitions
3
4use clap::{Parser, Subcommand};
5
6// Helper function to parse environment variable KEY=VALUE pairs
7fn parse_env_var(s: &str) -> Result<(String, String), String> {
8 let parts: Vec<&str> = s.splitn(2, '=').collect();
9 if parts.len() != 2 {
10 return Err(format!(
11 "Invalid environment variable format: '{}'. Expected 'KEY=VALUE'",
12 s
13 ));
14 }
15 Ok((parts[0].to_string(), parts[1].to_string()))
16}
17
18#[derive(Parser)]
19#[command(name = "lc")]
20#[command(
21 about = "LLM Client - A fast Rust-based LLM CLI tool with PDF support and RAG capabilities"
22)]
23#[command(version = "0.1.0")]
24pub struct Cli {
25 /// Direct prompt to send to the default model
26 #[arg(value_name = "PROMPT")]
27 pub prompt: Vec<String>,
28
29 /// Provider to use for the prompt
30 #[arg(short = 'p', long = "provider", global = true)]
31 pub provider: Option<String>,
32
33 /// Model to use for the prompt
34 #[arg(short = 'm', long = "model", global = true)]
35 pub model: Option<String>,
36
37 /// System prompt to use (when used with direct prompt)
38 #[arg(short = 's', long = "system")]
39 pub system_prompt: Option<String>,
40
41 /// Max tokens override (supports 'k' suffix, e.g., '2k' for 2000)
42 #[arg(long = "max-tokens")]
43 pub max_tokens: Option<String>,
44
45 /// Temperature override (0.0 to 2.0)
46 #[arg(long = "temperature")]
47 pub temperature: Option<String>,
48
49 /// Attach file(s) to the prompt (supports text files, PDFs with 'pdf' feature)
50 #[arg(short = 'a', long = "attach")]
51 pub attachments: Vec<String>,
52
53 /// Attach image(s) to the prompt (supports jpg, png, gif, webp, or URLs)
54 #[arg(short = 'i', long = "image")]
55 pub images: Vec<String>,
56
57 /// Attach audio file(s) for transcription (supports mp3, wav, flac, etc.)
58 #[arg(short = 'u', long = "audio")]
59 pub audio_files: Vec<String>,
60
61 /// Include tools from MCP server(s) (comma-separated server names)
62 #[arg(short = 't', long = "tools")]
63 pub tools: Option<String>,
64
65 /// Vector database name for RAG (Retrieval-Augmented Generation)
66 #[arg(short = 'v', long = "vectordb")]
67 pub vectordb: Option<String>,
68
69 /// Enable debug/verbose logging
70 #[arg(short = 'd', long = "debug")]
71 pub debug: bool,
72
73 /// Continue the current session (use existing session ID)
74 #[arg(short = 'c', long = "continue")]
75 pub continue_session: bool,
76
77 /// Chat ID to use or continue (alternative to --continue)
78 #[arg(long = "cid")]
79 pub chat_id: Option<String>,
80
81 /// Use search results as context (format: provider or provider:query)
82 #[arg(long = "use-search")]
83 pub use_search: Option<String>,
84
85 /// Enable streaming output for prompt responses
86 #[arg(long = "stream")]
87 pub stream: bool,
88
89 #[command(subcommand)]
90 pub command: Option<Commands>,
91}
92
93#[derive(clap::ValueEnum, Clone, Debug)]
94pub enum CompletionShell {
95 /// Bash shell
96 Bash,
97 /// Zsh shell
98 Zsh,
99 /// Fish shell
100 Fish,
101 /// PowerShell
102 PowerShell,
103 /// Elvish shell
104 Elvish,
105}
106
107#[derive(clap::ValueEnum, Clone, Debug)]
108pub enum McpServerType {
109 /// Standard I/O based MCP server
110 Stdio,
111 /// Server-Sent Events MCP server
112 Sse,
113 /// Streamable HTTP MCP server
114 Streamable,
115}
116
117#[derive(Subcommand)]
118pub enum Commands {
119 /// Provider management (alias: p)
120 #[command(alias = "p")]
121 Providers {
122 #[command(subcommand)]
123 command: ProviderCommands,
124 },
125 /// API key management (alias: k)
126 #[command(alias = "k")]
127 Keys {
128 #[command(subcommand)]
129 command: KeyCommands,
130 },
131 /// Log management (alias: l)
132 #[command(alias = "l")]
133 Logs {
134 #[command(subcommand)]
135 command: LogCommands,
136 },
137 /// Usage statistics and analytics (alias: u)
138 #[command(alias = "u")]
139 Usage {
140 #[command(subcommand)]
141 command: Option<UsageCommands>,
142 /// Show usage for the last N days
143 #[arg(short = 'd', long = "days")]
144 days: Option<u32>,
145 /// Show only token usage (default shows both tokens and requests)
146 #[arg(short = 't', long = "tokens")]
147 tokens_only: bool,
148 /// Show only request counts
149 #[arg(short = 'r', long = "requests")]
150 requests_only: bool,
151 /// Maximum number of items to show in charts
152 #[arg(short = 'n', long = "limit", default_value = "10")]
153 limit: usize,
154 },
155 /// Configuration management (alias: co)
156 #[command(alias = "co")]
157 Config {
158 #[command(subcommand)]
159 command: Option<ConfigCommands>,
160 },
161 /// Interactive chat mode (alias: c)
162 #[command(alias = "c")]
163 Chat {
164 /// Model to use for the chat
165 #[arg(short, long)]
166 model: Option<String>,
167 /// Provider to use for the chat
168 #[arg(short, long)]
169 provider: Option<String>,
170 /// Chat ID to use or continue
171 #[arg(long)]
172 cid: Option<String>,
173 /// Include tools from MCP server(s) (comma-separated server names)
174 #[arg(short = 't', long = "tools")]
175 tools: Option<String>,
176 /// Vector database name for RAG (Retrieval-Augmented Generation)
177 #[arg(short = 'v', long = "vectordb")]
178 database: Option<String>,
179 /// Enable debug/verbose logging
180 #[arg(short = 'd', long = "debug")]
181 debug: bool,
182 /// Attach image(s) to the chat (supports jpg, png, gif, webp, or URLs)
183 #[arg(short = 'i', long = "image")]
184 images: Vec<String>,
185 },
186 /// Global models management (alias: m)
187 #[command(alias = "m")]
188 Models {
189 #[command(subcommand)]
190 command: Option<ModelsCommands>,
191 /// Search query for models (case-insensitive)
192 #[arg(short = 'q', long = "query")]
193 query: Option<String>,
194 /// Filter models that support tools/function calling
195 #[arg(long = "tools")]
196 tools: bool,
197 /// Filter models that support reasoning
198 #[arg(long = "reasoning")]
199 reasoning: bool,
200 /// Filter models that support vision
201 #[arg(long = "vision")]
202 vision: bool,
203 /// Filter models that support audio
204 #[arg(long = "audio")]
205 audio: bool,
206 /// Filter models that support code generation
207 #[arg(long = "code")]
208 code: bool,
209 /// Filter models with minimum context length (e.g., 128k)
210 #[arg(long = "ctx")]
211 context_length: Option<String>,
212 /// Filter models with minimum input token length (e.g., 128k)
213 #[arg(long = "input")]
214 input_length: Option<String>,
215 /// Filter models with minimum output token length (e.g., 128k)
216 #[arg(long = "output")]
217 output_length: Option<String>,
218 /// Filter models with maximum input price per million tokens
219 #[arg(long = "input-price")]
220 input_price: Option<f64>,
221 /// Filter models with maximum output price per million tokens
222 #[arg(long = "output-price")]
223 output_price: Option<f64>,
224 },
225 /// Model alias management (alias: a)
226 #[command(alias = "a")]
227 Alias {
228 #[command(subcommand)]
229 command: AliasCommands,
230 },
231 /// Template management (alias: t)
232 #[command(alias = "t")]
233 Templates {
234 #[command(subcommand)]
235 command: TemplateCommands,
236 },
237 /// Proxy server (alias: pr)
238 #[command(alias = "pr")]
239 Proxy {
240 /// Port to listen on
241 #[arg(short = 'p', long = "port", default_value = "6789")]
242 port: u16,
243 /// Host to bind to
244 #[arg(long = "host", default_value = "127.0.0.1")]
245 host: String,
246 /// Filter by provider
247 #[arg(long = "provider")]
248 provider: Option<String>,
249 /// Filter by specific model (can be provider:model or alias)
250 #[arg(short = 'm', long = "model")]
251 model: Option<String>,
252 /// API key for authentication
253 #[arg(short = 'k', long = "key")]
254 api_key: Option<String>,
255 /// Generate a random API key
256 #[arg(short = 'g', long = "generate-key")]
257 generate_key: bool,
258 },
259 /// MCP server management
260 Mcp {
261 #[command(subcommand)]
262 command: McpCommands,
263 },
264 /// Generate embeddings for text (alias: e)
265 #[command(alias = "e")]
266 Embed {
267 /// Model to use for embeddings
268 #[arg(short, long)]
269 model: String,
270 /// Provider to use for embeddings
271 #[arg(short, long)]
272 provider: Option<String>,
273 /// Vector database name to store embeddings
274 #[arg(short = 'v', long = "vectordb")]
275 database: Option<String>,
276 /// Files to embed (supports glob patterns, including PDFs with 'pdf' feature)
277 #[arg(short = 'f', long = "files")]
278 files: Vec<String>,
279 /// Text to embed (optional if files are provided)
280 text: Option<String>,
281 /// Enable debug/verbose logging
282 #[arg(short = 'd', long = "debug")]
283 debug: bool,
284 },
285 /// Find similar text using vector similarity (alias: s)
286 #[command(alias = "s")]
287 Similar {
288 /// Model to use for embeddings (optional if database has existing model)
289 #[arg(short, long)]
290 model: Option<String>,
291 /// Provider to use for embeddings (optional if database has existing model)
292 #[arg(short, long)]
293 provider: Option<String>,
294 /// Vector database name to search
295 #[arg(short = 'v', long = "vectordb")]
296 database: String,
297 /// Number of similar results to return
298 #[arg(short, long, default_value = "5")]
299 limit: usize,
300 /// Query text to find similar content
301 query: String,
302 },
303 /// Vector database management (alias: v)
304 #[command(alias = "v")]
305 Vectors {
306 #[command(subcommand)]
307 command: VectorCommands,
308 },
309 /// Web chat proxy for non-OpenAI compatible services (alias: w)
310 #[command(alias = "w")]
311 WebChatProxy {
312 #[command(subcommand)]
313 command: WebChatProxyCommands,
314 },
315 /// Sync configuration files to/from cloud providers (alias: sy)
316 #[command(alias = "sy")]
317 Sync {
318 #[command(subcommand)]
319 command: SyncCommands,
320 },
321 /// Search provider management (alias: se)
322 #[command(alias = "se")]
323 Search {
324 #[command(subcommand)]
325 command: SearchCommands,
326 },
327 /// Generate images from text prompts (alias: img)
328 #[command(alias = "img")]
329 Image {
330 /// Text prompt for image generation
331 prompt: String,
332 /// Model to use for image generation
333 #[arg(short, long)]
334 model: Option<String>,
335 /// Provider to use for image generation
336 #[arg(short, long)]
337 provider: Option<String>,
338 /// Image size (e.g., "1024x1024", "512x512")
339 #[arg(short, long, default_value = "1024x1024")]
340 size: String,
341 /// Number of images to generate
342 #[arg(short, long, default_value = "1")]
343 count: u32,
344 /// Output directory for generated images
345 #[arg(short, long)]
346 output: Option<String>,
347 /// Enable debug/verbose logging
348 #[arg(short = 'd', long = "debug")]
349 debug: bool,
350 },
351 /// Transcribe audio to text (alias: tr)
352 #[command(alias = "tr")]
353 Transcribe {
354 /// Audio file(s) to transcribe (supports mp3, wav, flac, etc.)
355 audio_files: Vec<String>,
356 /// Model to use for transcription
357 #[arg(short, long)]
358 model: Option<String>,
359 /// Provider to use for transcription
360 #[arg(short, long)]
361 provider: Option<String>,
362 /// Language of the audio (ISO-639-1 format, e.g., "en", "es")
363 #[arg(short = 'l', long)]
364 language: Option<String>,
365 /// Optional prompt to guide the transcription
366 #[arg(long)]
367 prompt: Option<String>,
368 /// Response format (json, text, srt, verbose_json, vtt)
369 #[arg(short = 'f', long, default_value = "text")]
370 format: String,
371 /// Temperature for transcription (0.0 to 1.0)
372 #[arg(long)]
373 temperature: Option<f32>,
374 /// Output file for transcription (optional, prints to stdout if not specified)
375 #[arg(short, long)]
376 output: Option<String>,
377 /// Enable debug/verbose logging
378 #[arg(short = 'd', long = "debug")]
379 debug: bool,
380 },
381 /// Convert text to speech
382 TTS {
383 /// Text to convert to speech
384 text: String,
385 /// Model to use for TTS
386 #[arg(short, long)]
387 model: Option<String>,
388 /// Provider to use for TTS
389 #[arg(short, long)]
390 provider: Option<String>,
391 /// Voice to use (e.g., alloy, echo, fable, onyx, nova, shimmer)
392 #[arg(short = 'v', long, default_value = "alloy")]
393 voice: String,
394 /// Output audio format (mp3, opus, aac, flac, wav, pcm)
395 #[arg(short = 'f', long, default_value = "mp3")]
396 format: String,
397 /// Speech speed (0.25 to 4.0)
398 #[arg(short = 's', long)]
399 speed: Option<f32>,
400 /// Output file for audio (required)
401 #[arg(short, long)]
402 output: String,
403 /// Enable debug/verbose logging
404 #[arg(short = 'd', long = "debug")]
405 debug: bool,
406 },
407 /// Dump metadata JSON from models cache (alias: dump)
408 #[command(alias = "dump")]
409 DumpMetadata {
410 /// Specific provider to dump (optional - dumps all if not specified)
411 provider: Option<String>,
412 /// List available cached metadata files
413 #[arg(short, long)]
414 list: bool,
415 },
416 /// Generate shell completions
417 Completions {
418 /// Shell to generate completions for
419 #[arg(value_enum)]
420 shell: CompletionShell,
421 },
422}
423
424// Command enums
425#[derive(Subcommand)]
426pub enum ModelsCommands {
427 /// Refresh the models cache (alias: r)
428 #[command(alias = "r")]
429 Refresh,
430 /// Show cache information (alias: i)
431 #[command(alias = "i")]
432 Info,
433 /// Dump raw /models responses to JSON files (alias: d)
434 #[command(alias = "d")]
435 Dump,
436 /// List embedding models (alias: e)
437 #[command(alias = "e")]
438 Embed,
439 /// Manage model paths for extraction (alias: p)
440 #[command(alias = "p")]
441 Path {
442 #[command(subcommand)]
443 command: ModelsPathCommands,
444 },
445 /// Manage model tags and extraction rules (alias: t)
446 #[command(alias = "t")]
447 Tags {
448 #[command(subcommand)]
449 command: ModelsTagsCommands,
450 },
451 /// Filter models by tags (alias: f)
452 #[command(alias = "f")]
453 Filter {
454 /// Tags to filter by (comma-separated)
455 #[arg(short = 't', long = "tag")]
456 tags: String,
457 },
458}
459
460#[derive(Subcommand)]
461pub enum ModelsPathCommands {
462 /// List all model extraction paths (alias: l)
463 #[command(alias = "l")]
464 List,
465 /// Add a new model extraction path (alias: a)
466 #[command(alias = "a")]
467 Add {
468 /// JQ-style path to add
469 path: String,
470 },
471 /// Delete a model extraction path (alias: d)
472 #[command(alias = "d")]
473 Delete {
474 /// Path to delete
475 path: String,
476 },
477}
478
479#[derive(Subcommand)]
480pub enum ModelsTagsCommands {
481 /// List all tags and their rules (alias: l)
482 #[command(alias = "l")]
483 List,
484 /// Add a rule to a tag (alias: a)
485 #[command(alias = "a")]
486 Add {
487 /// Tag name
488 tag: String,
489 /// Extraction rule (JQ-style path or search pattern)
490 rule: String,
491 },
492}
493
494#[derive(Subcommand)]
495pub enum AliasCommands {
496 /// Add a new alias (alias: a)
497 #[command(alias = "a")]
498 Add {
499 /// Alias name
500 name: String,
501 /// Provider and model in format provider:model
502 target: String,
503 },
504 /// Remove an alias (alias: d)
505 #[command(alias = "d")]
506 Delete {
507 /// Alias name to remove
508 name: String,
509 },
510 /// List all aliases (alias: l)
511 #[command(alias = "l")]
512 List,
513}
514
515#[derive(Subcommand)]
516pub enum TemplateCommands {
517 /// Add a new template (alias: a)
518 #[command(alias = "a")]
519 Add {
520 /// Template name
521 name: String,
522 /// Template prompt content
523 prompt: String,
524 },
525 /// Remove a template (alias: d)
526 #[command(alias = "d")]
527 Delete {
528 /// Template name to remove
529 name: String,
530 },
531 /// List all templates (alias: l)
532 #[command(alias = "l")]
533 List,
534}
535
536#[derive(Subcommand)]
537pub enum ProviderCommands {
538 /// Install a provider from the registry (alias: i)
539 #[command(alias = "i")]
540 Install {
541 /// Provider name to install
542 name: String,
543 /// Force reinstall even if already installed
544 #[arg(short = 'f', long = "force")]
545 force: bool,
546 },
547 /// Update installed providers (alias: up)
548 #[command(alias = "up")]
549 Upgrade {
550 /// Provider name to update (updates all if not specified)
551 name: Option<String>,
552 },
553 /// Uninstall a provider (alias: un)
554 #[command(alias = "un")]
555 Uninstall {
556 /// Provider name to uninstall
557 name: String,
558 },
559 /// List available providers from registry (alias: av)
560 #[command(alias = "av")]
561 Available {
562 /// Show only official providers
563 #[arg(long = "official")]
564 official: bool,
565 /// Filter by tag
566 #[arg(short = 't', long = "tag")]
567 tag: Option<String>,
568 },
569 /// Add a new provider (alias: a)
570 #[command(alias = "a")]
571 Add {
572 /// Provider name
573 name: String,
574 /// Provider endpoint URL
575 url: String,
576 /// Custom models endpoint path (default: /models)
577 #[arg(short = 'm', long = "models-path")]
578 models_path: Option<String>,
579 /// Custom chat completions endpoint path (default: /chat/completions)
580 #[arg(short = 'c', long = "chat-path")]
581 chat_path: Option<String>,
582 },
583 /// Update an existing provider (alias: u)
584 #[command(alias = "u")]
585 Update {
586 /// Provider name
587 name: String,
588 /// Provider endpoint URL
589 url: String,
590 },
591 /// Remove a provider (alias: r)
592 #[command(alias = "r")]
593 Remove {
594 /// Provider name
595 name: String,
596 },
597 /// List all providers (alias: l)
598 #[command(alias = "l")]
599 List,
600 /// List available models for a provider (alias: m)
601 #[command(alias = "m")]
602 Models {
603 /// Provider name
604 name: String,
605 /// Refresh the models cache for this provider (alias: r)
606 #[arg(short = 'r', long = "refresh")]
607 refresh: bool,
608 },
609 /// Manage custom headers for a provider (alias: h)
610 #[command(alias = "h")]
611 Headers {
612 /// Provider name
613 provider: String,
614 #[command(subcommand)]
615 command: HeaderCommands,
616 },
617 /// Manage provider variables for path templating (alias: v)
618 #[command(alias = "v")]
619 Vars {
620 /// Provider name
621 provider: String,
622 #[command(subcommand)]
623 command: ProviderVarsCommands,
624 },
625 /// Set token URL for a provider (alias: t)
626 #[command(alias = "t")]
627 TokenUrl {
628 /// Provider name
629 provider: String,
630 /// Token URL for dynamic token retrieval
631 url: String,
632 },
633 /// Manage provider API paths (alias: path)
634 #[command(alias = "path")]
635 Paths {
636 /// Provider name
637 provider: String,
638 #[command(subcommand)]
639 command: ProviderPathCommands,
640 },
641}
642
643#[derive(Subcommand)]
644pub enum ProviderVarsCommands {
645 /// Set a provider variable (alias: s)
646 #[command(alias = "s")]
647 Set {
648 /// Variable key (e.g., project, location)
649 key: String,
650 /// Variable value
651 value: String,
652 },
653 /// Get a provider variable (alias: g)
654 #[command(alias = "g")]
655 Get {
656 /// Variable key
657 key: String,
658 },
659 /// List all provider variables (alias: l)
660 #[command(alias = "l")]
661 List,
662}
663
664#[derive(Subcommand)]
665pub enum ProviderPathCommands {
666 /// Add or update a provider path (alias: a)
667 #[command(alias = "a")]
668 Add {
669 /// Models path
670 #[arg(short = 'm', long = "models")]
671 models_path: Option<String>,
672 /// Chat completions path
673 #[arg(short = 'c', long = "chat")]
674 chat_path: Option<String>,
675 /// Image generations path
676 #[arg(short = 'i', long = "images")]
677 images_path: Option<String>,
678 /// Embeddings path
679 #[arg(short = 'e', long = "embeddings")]
680 embeddings_path: Option<String>,
681 },
682 /// Delete a provider path (alias: d)
683 #[command(alias = "d")]
684 Delete {
685 /// Delete models path
686 #[arg(short = 'm', long = "models")]
687 models: bool,
688 /// Delete chat completions path
689 #[arg(short = 'c', long = "chat")]
690 chat: bool,
691 /// Delete image generations path
692 #[arg(short = 'i', long = "images")]
693 images: bool,
694 /// Delete embeddings path
695 #[arg(short = 'e', long = "embeddings")]
696 embeddings: bool,
697 },
698 /// List all provider paths (alias: l)
699 #[command(alias = "l")]
700 List,
701}
702
703#[derive(Subcommand)]
704pub enum HeaderCommands {
705 /// Add a custom header (alias: a)
706 #[command(alias = "a")]
707 Add {
708 /// Header name
709 name: String,
710 /// Header value
711 value: String,
712 },
713 /// Remove a custom header (alias: d)
714 #[command(alias = "d")]
715 Delete {
716 /// Header name
717 name: String,
718 },
719 /// List all custom headers (alias: l)
720 #[command(alias = "l")]
721 List,
722}
723
724#[derive(Subcommand)]
725pub enum KeyCommands {
726 /// Add API key for a provider (alias: a)
727 #[command(alias = "a")]
728 Add {
729 /// Provider name
730 name: String,
731 },
732 /// List providers with API keys (alias: l)
733 #[command(alias = "l")]
734 List,
735 /// Get API key for a provider (alias: g)
736 #[command(alias = "g")]
737 Get {
738 /// Provider name
739 name: String,
740 },
741 /// Remove API key for a provider (alias: r)
742 #[command(alias = "r")]
743 Remove {
744 /// Provider name
745 name: String,
746 },
747}
748
749#[derive(Subcommand)]
750pub enum LogCommands {
751 /// Show all logs (alias: sh)
752 #[command(alias = "sh")]
753 Show {
754 /// Show minimal table format
755 #[arg(long)]
756 minimal: bool,
757 },
758 /// Show recent logs (alias: r)
759 #[command(alias = "r")]
760 Recent {
761 #[command(subcommand)]
762 command: Option<RecentCommands>,
763 /// Number of recent entries to show
764 #[arg(short, long, default_value = "10")]
765 count: usize,
766 },
767 /// Show current session logs (alias: c)
768 #[command(alias = "c")]
769 Current,
770 /// Show database statistics (alias: s)
771 #[command(alias = "s")]
772 Stats,
773 /// Purge all logs (alias: p)
774 #[command(alias = "p")]
775 Purge {
776 /// Confirm purge without prompt
777 #[arg(long)]
778 yes: bool,
779 /// Purge logs older than N days
780 #[arg(long)]
781 older_than_days: Option<u32>,
782 /// Keep only the most recent N entries
783 #[arg(long)]
784 keep_recent: Option<usize>,
785 /// Purge when database exceeds N MB
786 #[arg(long)]
787 max_size_mb: Option<u64>,
788 },
789}
790
791#[derive(Subcommand)]
792pub enum RecentCommands {
793 /// Get last answer from LLM (alias: a)
794 #[command(alias = "a")]
795 Answer {
796 #[command(subcommand)]
797 command: Option<AnswerCommands>,
798 },
799 /// Get last question/prompt asked to LLM (alias: q)
800 #[command(alias = "q")]
801 Question,
802 /// Get model used in last interaction (alias: m)
803 #[command(alias = "m")]
804 Model,
805 /// Get session ID of last interaction (alias: s)
806 #[command(alias = "s")]
807 Session,
808}
809
810#[derive(Subcommand)]
811pub enum UsageCommands {
812 /// Show daily usage statistics (alias: d)
813 #[command(alias = "d")]
814 Daily {
815 /// Number of days to show
816 #[arg(short = 'n', long = "count", default_value = "30")]
817 count: usize,
818 },
819 /// Show weekly usage statistics (alias: w)
820 #[command(alias = "w")]
821 Weekly {
822 /// Number of weeks to show
823 #[arg(short = 'n', long = "count", default_value = "12")]
824 count: usize,
825 },
826 /// Show monthly usage statistics (alias: m)
827 #[command(alias = "m")]
828 Monthly {
829 /// Number of months to show
830 #[arg(short = 'n', long = "count", default_value = "12")]
831 count: usize,
832 },
833 /// Show yearly usage statistics (alias: y)
834 #[command(alias = "y")]
835 Yearly {
836 /// Number of years to show
837 #[arg(short = 'n', long = "count", default_value = "5")]
838 count: usize,
839 },
840 /// Show top models by usage (alias: models)
841 #[command(alias = "models")]
842 Models {
843 /// Number of models to show
844 #[arg(short = 'n', long = "count", default_value = "10")]
845 count: usize,
846 },
847}
848
849#[derive(Subcommand)]
850pub enum AnswerCommands {
851 /// Extract code blocks from last answer (alias: c)
852 #[command(alias = "c")]
853 Code,
854}
855
856#[derive(Subcommand)]
857pub enum ConfigCommands {
858 /// Set configuration values (alias: s)
859 #[command(alias = "s")]
860 Set {
861 #[command(subcommand)]
862 command: SetCommands,
863 },
864 /// Get configuration values (alias: g)
865 #[command(alias = "g")]
866 Get {
867 #[command(subcommand)]
868 command: GetCommands,
869 },
870 /// Delete/unset configuration values (alias: d)
871 #[command(alias = "d")]
872 Delete {
873 #[command(subcommand)]
874 command: DeleteCommands,
875 },
876 /// Show configuration directory path (alias: p)
877 #[command(alias = "p")]
878 Path,
879}
880
881#[derive(Subcommand)]
882pub enum SetCommands {
883 /// Set default provider (alias: p)
884 #[command(alias = "p")]
885 Provider {
886 /// Provider name
887 name: String,
888 },
889 /// Set default model (alias: m)
890 #[command(alias = "m")]
891 Model {
892 /// Model name
893 name: String,
894 },
895 /// Set system prompt (alias: s)
896 #[command(alias = "s")]
897 SystemPrompt {
898 /// System prompt text
899 prompt: String,
900 },
901 /// Set max tokens (alias: mt)
902 #[command(alias = "mt")]
903 MaxTokens {
904 /// Max tokens value (supports 'k' suffix, e.g., '2k' for 2000)
905 value: String,
906 },
907 /// Set temperature (alias: te)
908 #[command(alias = "te")]
909 Temperature {
910 /// Temperature value (0.0 to 2.0)
911 value: String,
912 },
913 /// Set default search provider (alias: se)
914 #[command(alias = "se")]
915 Search {
916 /// Search provider name
917 name: String,
918 },
919 /// Set streaming output preference (alias: st)
920 #[command(alias = "st")]
921 Stream {
922 /// Stream output (true/false)
923 value: String,
924 },
925}
926
927#[derive(Subcommand)]
928pub enum GetCommands {
929 /// Get default provider (alias: p)
930 #[command(alias = "p")]
931 Provider,
932 /// Get default model (alias: m)
933 #[command(alias = "m")]
934 Model,
935 /// Get system prompt (alias: s)
936 #[command(alias = "s")]
937 SystemPrompt,
938 /// Get max tokens (alias: mt)
939 #[command(alias = "mt")]
940 MaxTokens,
941 /// Get temperature (alias: te)
942 #[command(alias = "te")]
943 Temperature,
944 /// Get default search provider (alias: se)
945 #[command(alias = "se")]
946 Search,
947 /// Get streaming output preference (alias: st)
948 #[command(alias = "st")]
949 Stream,
950}
951
952#[derive(Subcommand)]
953pub enum DeleteCommands {
954 /// Delete default provider (alias: p)
955 #[command(alias = "p")]
956 Provider,
957 /// Delete default model (alias: m)
958 #[command(alias = "m")]
959 Model,
960 /// Delete system prompt (alias: s)
961 #[command(alias = "s")]
962 SystemPrompt,
963 /// Delete max tokens (alias: mt)
964 #[command(alias = "mt")]
965 MaxTokens,
966 /// Delete temperature (alias: te)
967 #[command(alias = "te")]
968 Temperature,
969 /// Delete default search provider (alias: se)
970 #[command(alias = "se")]
971 Search,
972 /// Delete streaming output preference (alias: st)
973 #[command(alias = "st")]
974 Stream,
975}
976
977#[derive(Subcommand)]
978pub enum VectorCommands {
979 /// List all vector databases (alias: l)
980 #[command(alias = "l")]
981 List,
982 /// Create a new vector database (alias: c)
983 #[command(alias = "c")]
984 Create {
985 /// Database name
986 name: String,
987 },
988 /// Delete a vector database (alias: d)
989 #[command(alias = "d")]
990 Delete {
991 /// Database name
992 name: String,
993 /// Confirm deletion without prompt
994 #[arg(long)]
995 yes: bool,
996 },
997 /// Show database information (alias: i)
998 #[command(alias = "i")]
999 Info {
1000 /// Database name
1001 name: String,
1002 },
1003 /// Show database statistics (alias: s)
1004 #[command(alias = "s")]
1005 Stats {
1006 /// Database name
1007 name: String,
1008 },
1009 /// Clear all embeddings from database (alias: cl)
1010 #[command(alias = "cl")]
1011 Clear {
1012 /// Database name
1013 name: String,
1014 /// Confirm clear without prompt
1015 #[arg(long)]
1016 yes: bool,
1017 },
1018}
1019
1020#[derive(Subcommand)]
1021pub enum WebChatProxyCommands {
1022 /// Start web chat proxy server (alias: s)
1023 #[command(alias = "s")]
1024 Start {
1025 /// Port to listen on
1026 #[arg(short = 'p', long = "port", default_value = "8080")]
1027 port: u16,
1028 /// Host to bind to
1029 #[arg(long = "host", default_value = "127.0.0.1")]
1030 host: String,
1031 /// Enable CORS for cross-origin requests
1032 #[arg(long = "cors")]
1033 cors: bool,
1034 },
1035}
1036
1037#[derive(Subcommand)]
1038pub enum SyncCommands {
1039 /// List supported cloud providers (alias: p)
1040 #[command(alias = "p")]
1041 Providers,
1042 /// Configure cloud provider settings (alias: c)
1043 #[command(alias = "c")]
1044 Configure {
1045 /// Cloud provider name (e.g., s3, cloudflare, backblaze)
1046 provider: String,
1047 #[command(subcommand)]
1048 command: Option<ConfigureCommands>,
1049 },
1050 /// Sync configuration to cloud provider
1051 To {
1052 /// Cloud provider name (e.g., s3, cloudflare, backblaze)
1053 provider: String,
1054 /// Encrypt files before uploading
1055 #[arg(short = 'e', long = "encrypted")]
1056 encrypted: bool,
1057 /// Skip confirmation prompt
1058 #[arg(short = 'y', long = "yes")]
1059 yes: bool,
1060 },
1061 /// Sync configuration from cloud provider
1062 From {
1063 /// Cloud provider name (e.g., s3, cloudflare, backblaze)
1064 provider: String,
1065 /// Decrypt files after downloading
1066 #[arg(short = 'e', long = "encrypted")]
1067 encrypted: bool,
1068 /// Skip confirmation prompt
1069 #[arg(short = 'y', long = "yes")]
1070 yes: bool,
1071 },
1072}
1073
1074#[derive(Subcommand)]
1075pub enum ConfigureCommands {
1076 /// Initial sync setup (alias: s)
1077 #[command(alias = "s")]
1078 Setup,
1079 /// Show current sync configuration (alias: sh)
1080 #[command(alias = "sh")]
1081 Show,
1082 /// Remove sync configuration (alias: r)
1083 #[command(alias = "r")]
1084 Remove,
1085}
1086
1087#[derive(Subcommand)]
1088pub enum SearchCommands {
1089 /// Manage search providers (alias: p)
1090 #[command(alias = "p")]
1091 Provider {
1092 #[command(subcommand)]
1093 command: SearchProviderCommands,
1094 },
1095 /// Query a search provider directly (alias: q)
1096 #[command(alias = "q")]
1097 Query {
1098 /// Search provider name
1099 provider: String,
1100 /// Search query
1101 query: String,
1102 /// Output format (json or md/markdown)
1103 #[arg(short = 'f', long = "format", default_value = "md")]
1104 format: String,
1105 /// Number of results to return
1106 #[arg(short = 'n', long = "count", default_value = "5")]
1107 count: usize,
1108 },
1109}
1110
1111#[derive(Subcommand)]
1112pub enum SearchProviderCommands {
1113 /// Add a search provider (alias: a)
1114 #[command(alias = "a")]
1115 Add {
1116 /// Provider name
1117 name: String,
1118 /// Provider URL (auto-detects type)
1119 url: String,
1120 },
1121 /// List all search providers (alias: l)
1122 #[command(alias = "l")]
1123 List,
1124 /// Delete a search provider (alias: d)
1125 #[command(alias = "d")]
1126 Delete {
1127 /// Provider name
1128 name: String,
1129 },
1130 /// Set provider headers/configuration (alias: s)
1131 #[command(alias = "s")]
1132 Set {
1133 /// Provider name
1134 provider: String,
1135 /// Header name (e.g., X-API-KEY, Authorization)
1136 header_name: String,
1137 /// Header value
1138 header_value: String,
1139 },
1140}
1141
1142#[derive(Subcommand)]
1143pub enum McpCommands {
1144 /// Add a new MCP server (alias: a)
1145 #[command(alias = "a")]
1146 Add {
1147 /// Server name
1148 name: String,
1149 /// Command or URL for the MCP server
1150 command_or_url: String,
1151 /// MCP server type
1152 #[arg(long = "type", value_enum)]
1153 server_type: McpServerType,
1154 /// Environment variables (can be specified multiple times as KEY=VALUE)
1155 #[arg(short = 'e', long = "env", value_parser = parse_env_var)]
1156 env: Vec<(String, String)>,
1157 },
1158 /// Delete an MCP server configuration (alias: d)
1159 #[command(alias = "d")]
1160 Delete {
1161 /// Server name
1162 name: String,
1163 },
1164 /// List all configured MCP servers (alias: l)
1165 #[command(alias = "l")]
1166 List,
1167 /// Stop an MCP server connection (alias: st)
1168 #[command(alias = "st")]
1169 Stop {
1170 /// Server name
1171 name: String,
1172 },
1173 /// List functions exposed by a running MCP server (alias: f)
1174 #[command(alias = "f")]
1175 Functions {
1176 /// Server name
1177 name: String,
1178 },
1179 /// Invoke a function from a running MCP server (alias: i)
1180 #[command(alias = "i")]
1181 Invoke {
1182 /// Server name
1183 name: String,
1184 /// Function name
1185 function: String,
1186 /// Function arguments
1187 args: Vec<String>,
1188 },
1189 /// Start an MCP server (alias: s)
1190 #[command(alias = "s")]
1191 Start {
1192 /// Server name
1193 name: String,
1194 /// Server command (optional - uses stored configuration if not provided)
1195 command: Option<String>,
1196 /// Server arguments
1197 #[arg(short = 'a', long = "args")]
1198 args: Vec<String>,
1199 },
1200 /// Show MCP server status (alias: st)
1201 #[command(alias = "stat")]
1202 Status {
1203 /// Server name (optional, shows all if not specified)
1204 name: Option<String>,
1205 },
1206}