summaryrefslogtreecommitdiff
path: root/cli.py
blob: b940d55d1c9206164601bf0fdea2ccf6ed41abb8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
#!/usr/bin/env python
# COPYRIGHT 2025 Thomas Grothe
import argparse
import os
import sys
import json
import ai_api_module

#this is the CLI program used to interact with the GAI python module. 

default_model = "gemini-2.0-flash-exp"

def main():
    """Main function to parse arguments and execute commands"""
    parser = argparse.ArgumentParser(description="CLI for calling AI APIs with file attachment support")
    parser.add_argument(
        "--apikey", default=os.getenv("GEMINI_API_KEY"), help="API key for the service"
    )
    parser.add_argument("--modelid", default=default_model, help=f"ID of the model to use (default={default_model})")
    parser.add_argument("--list-models", action="store_true", help="list the available models")
    
    # Conversation management
    parser.add_argument("--new", "-n", action="store_true", help="Start a new conversation")
    parser.add_argument("--save-conversation", metavar="FILE", help="Save conversation to file")
    parser.add_argument("--load-conversation", metavar="FILE", help="Load conversation from file")
    parser.add_argument("--list-conversations", action="store_true", help="List saved conversations")
    parser.add_argument("--clear", action="store_true", help="Clear conversation history")
    parser.add_argument("--system-instruction", metavar="TEXT", help="Set system instruction for the conversation")
    
    # Query parameters
    parser.add_argument("--query", "-q", default="", help="Query to be sent to the assistant")
    parser.add_argument("--topp", type=float, default=0.9, help="Top P value for the model")
    parser.add_argument("--temperature", type=float, default=0.7, help="Temperature value for the model")
    parser.add_argument("--max-tokens", type=int, default=8192, help="Maximum output tokens")
    parser.add_argument("--stream", action="store_true", help="Enable streaming response")
    parser.add_argument("--no-stream", action="store_true", help="Disable streaming response")
    parser.add_argument("--output_mode", "-o", default='text', help="Output mode (text or json)")
    parser.add_argument("--count-tokens", action="store_true", help="Count tokens in query without sending")
    
    parser.add_argument("extra_query", nargs="*")

    args = parser.parse_args()
    
    # Get API key
    if args.apikey:
        ai_api_module.api_key = args.apikey
    else:
        ai_api_module.get_api_key()
        if not ai_api_module.api_key:
            print("Error: API key not provided. Set GEMINI_API_KEY environment variable.")
            sys.exit(1)
    
    # Handle system instruction
    if args.system_instruction:
        ai_api_module.set_system_instruction(args.system_instruction)
        print(f"System instruction set")
    
    # Handle conversation management
    if args.new:
        ai_api_module.clear_conversation()
        print("Started new conversation")
    
    if args.load_conversation:
        if ai_api_module.load_conversation(args.load_conversation):
            print(f"Loaded conversation from {args.load_conversation}")
        else:
            print(f"Failed to load conversation from {args.load_conversation}")
            sys.exit(1)
    
    if args.list_conversations:
        success, result = ai_api_module.list_saved_conversations()
        if success:
            if not result:
                print("No saved conversations found")
            else:
                print("Saved conversations:")
                for conv in result:
                    print(f"  {conv['filename']}")
                    print(f"    Saved: {conv['saved_at']}")
                    print(f"    Messages: {conv['message_count']}")
                    print()
        else:
            print(f"Error: {result}")
        return
    
    if args.clear:
        ai_api_module.clear_conversation()
        print("Conversation history cleared")
        return
    
    # List models
    if args.list_models:
        success, result = ai_api_module.list_models(args.output_mode)
        if success:
            for model in result:
                if args.output_mode == 'json':
                    print(json.dumps(model, indent=2))
                else:
                    print(f"Model: {model['display_name']}")
                    print(f"  Name: {model['name']}")
                    print(f"  Description: {model.get('description', 'N/A')}")
                    print(f"  Input tokens: {model.get('input_token_limit', 'N/A')}")
                    print(f"  Output tokens: {model.get('output_token_limit', 'N/A')}")
                    print()
        else:
            print(f'Error: {result}')
        return

    # Process query
    if args.query or args.extra_query:
        query = args.query
        if args.extra_query:
            if query:
                query += " " + " ".join(args.extra_query)
            else:
                query = " ".join(args.extra_query)
        
        # Count tokens if requested
        if args.count_tokens:
            success, count = ai_api_module.count_tokens(args.modelid, query)
            if success:
                print(f"Token count: {count}")
            else:
                print(f"Error counting tokens: {count}")
            return
        
        # Determine streaming
        use_stream = args.stream and not args.no_stream
        
        response = ai_api_module.query( 
            args.modelid, 
            query,
            args.topp,
            args.temperature, 
            use_stream,
            args.max_tokens,
        )
        
        if response and not use_stream:
            print(response)
        
        # Auto-save conversation if requested
        if args.save_conversation:
            filepath = ai_api_module.save_conversation(args.save_conversation)
            print(f"\nConversation saved to {filepath}")
    else:
        parser.print_help()

if __name__ == "__main__":
    main()