1+ #!/usr/bin/env python3
2+ """
3+ Gradient CLI Tool
4+
5+ A command-line interface for common Gradient operations.
6+ """
7+
8+ import argparse
9+ import json
10+ import sys
11+ from pathlib import Path
12+ from typing import Optional
13+
14+ try :
15+ from gradient import Gradient
16+ from gradient ._utils import (
17+ validate_api_key ,
18+ validate_client_credentials ,
19+ validate_client_instance ,
20+ get_available_models ,
21+ is_model_available ,
22+ get_model_info ,
23+ )
24+ except ImportError as e :
25+ print (f"Error importing gradient: { e } " )
26+ print ("Make sure gradient is installed and PYTHONPATH is set correctly" )
27+ sys .exit (1 )
28+
29+
30+ def create_client (access_token : Optional [str ] = None ,
31+ model_key : Optional [str ] = None ,
32+ agent_key : Optional [str ] = None ,
33+ agent_endpoint : Optional [str ] = None ) -> Gradient :
34+ """Create and validate a Gradient client."""
35+ try :
36+ client = Gradient (
37+ access_token = access_token ,
38+ model_access_key = model_key ,
39+ agent_access_key = agent_key ,
40+ agent_endpoint = agent_endpoint ,
41+ )
42+ validate_client_instance (client )
43+ return client
44+ except Exception as e :
45+ print (f"Error creating client: { e } " )
46+ sys .exit (1 )
47+
48+
49+ def cmd_validate (args ):
50+ """Validate API keys and client configuration."""
51+ print ("🔍 Validating API keys and client configuration..." )
52+
53+ # Validate individual keys
54+ if args .access_token :
55+ if validate_api_key (args .access_token ):
56+ print ("✅ Access token format is valid" )
57+ else :
58+ print ("❌ Access token format is invalid" )
59+ return
60+
61+ if args .model_key :
62+ if validate_api_key (args .model_key ):
63+ print ("✅ Model access key format is valid" )
64+ else :
65+ print ("❌ Model access key format is invalid" )
66+ return
67+
68+ if args .agent_key :
69+ if validate_api_key (args .agent_key ):
70+ print ("✅ Agent access key format is valid" )
71+ else :
72+ print ("❌ Agent access key format is invalid" )
73+ return
74+
75+ # Validate client credentials
76+ try :
77+ validate_client_credentials (
78+ access_token = args .access_token ,
79+ model_access_key = args .model_key ,
80+ agent_access_key = args .agent_key ,
81+ agent_endpoint = args .agent_endpoint
82+ )
83+ print ("✅ Client credentials validation passed" )
84+ except ValueError as e :
85+ print (f"❌ Client credentials validation failed: { e } " )
86+ return
87+
88+ # Test client creation
89+ try :
90+ client = create_client (args .access_token , args .model_key , args .agent_key , args .agent_endpoint )
91+ print ("✅ Client instance created and validated successfully" )
92+ except Exception as e :
93+ print (f"❌ Client creation failed: { e } " )
94+
95+
96+ def cmd_models (args ):
97+ """List and query available models."""
98+ print ("🤖 Available Models:" )
99+
100+ models = get_available_models ()
101+ for model in models :
102+ status = "✅" if is_model_available (model ) else "❌"
103+ print (f" { status } { model } " )
104+
105+ if args .info :
106+ print (f"\n 📋 Detailed info for '{ args .info } ':" )
107+ info = get_model_info (args .info )
108+ if info :
109+ print (json .dumps (info , indent = 2 ))
110+ else :
111+ print (f"❌ Model '{ args .info } ' not found" )
112+
113+
114+ def cmd_test_connection (args ):
115+ """Test connection to Gradient services."""
116+ print ("🔌 Testing connection to Gradient services..." )
117+
118+ client = create_client (args .access_token , args .model_key , args .agent_key , args .agent_endpoint )
119+
120+ # Test basic connectivity by trying to get models
121+ try :
122+ # This would normally make an API call, but we'll use our cached models for now
123+ models = get_available_models ()
124+ print (f"✅ Connection successful - { len (models )} models available" )
125+ except Exception as e :
126+ print (f"❌ Connection test failed: { e } " )
127+
128+
129+ def cmd_chat (args ):
130+ """Simple chat interface for testing."""
131+ print ("💬 Gradient Chat Interface" )
132+ print ("Type 'quit' or 'exit' to end the conversation" )
133+ print ("-" * 50 )
134+
135+ client = create_client (args .access_token , args .model_key , args .agent_key , args .agent_endpoint )
136+
137+ if not client .model_access_key :
138+ print ("❌ Model access key required for chat functionality" )
139+ return
140+
141+ messages = []
142+
143+ while True :
144+ try :
145+ user_input = input ("\n You: " ).strip ()
146+ if user_input .lower () in ['quit' , 'exit' , 'q' ]:
147+ print ("👋 Goodbye!" )
148+ break
149+
150+ if not user_input :
151+ continue
152+
153+ messages .append ({"role" : "user" , "content" : user_input })
154+
155+ print ("🤖 Assistant: " , end = "" , flush = True )
156+
157+ # For streaming responses
158+ if args .stream :
159+ response = client .chat .completions .create (
160+ messages = messages ,
161+ model = args .model or "llama3.3-70b-instruct" ,
162+ stream = True
163+ )
164+
165+ full_response = ""
166+ for chunk in response :
167+ if chunk .choices and chunk .choices [0 ].delta and chunk .choices [0 ].delta .content :
168+ content = chunk .choices [0 ].delta .content
169+ print (content , end = "" , flush = True )
170+ full_response += content
171+
172+ messages .append ({"role" : "assistant" , "content" : full_response })
173+ print () # New line after streaming
174+
175+ else :
176+ response = client .chat .completions .create (
177+ messages = messages ,
178+ model = args .model or "llama3.3-70b-instruct" ,
179+ stream = False
180+ )
181+
182+ if response .choices and response .choices [0 ].message :
183+ content = response .choices [0 ].message .content
184+ print (content )
185+ messages .append ({"role" : "assistant" , "content" : content })
186+
187+ except KeyboardInterrupt :
188+ print ("\n 👋 Goodbye!" )
189+ break
190+ except Exception as e :
191+ print (f"❌ Error: { e } " )
192+
193+
194+ def main ():
195+ """Main CLI entry point."""
196+ parser = argparse .ArgumentParser (
197+ description = "Gradient CLI - Command-line interface for Gradient AI operations" ,
198+ formatter_class = argparse .RawDescriptionHelpFormatter ,
199+ epilog = """
200+ Examples:
201+ # Validate API keys
202+ gradient-cli validate --access-token sk-1234567890abcdef
203+
204+ # List available models
205+ gradient-cli models
206+
207+ # Get model info
208+ gradient-cli models --info llama3.3-70b-instruct
209+
210+ # Test connection
211+ gradient-cli test-connection --access-token sk-1234567890abcdef
212+
213+ # Start chat interface
214+ gradient-cli chat --model-key grad-1234567890abcdef --model llama3.3-70b-instruct
215+ """
216+ )
217+
218+ parser .add_argument (
219+ "--access-token" ,
220+ help = "DigitalOcean access token"
221+ )
222+
223+ parser .add_argument (
224+ "--model-key" ,
225+ help = "Gradient model access key"
226+ )
227+
228+ parser .add_argument (
229+ "--agent-key" ,
230+ help = "Gradient agent access key"
231+ )
232+
233+ parser .add_argument (
234+ "--agent-endpoint" ,
235+ help = "Agent endpoint URL"
236+ )
237+
238+ subparsers = parser .add_subparsers (dest = "command" , help = "Available commands" )
239+
240+ # Validate command
241+ validate_parser = subparsers .add_parser (
242+ "validate" ,
243+ help = "Validate API keys and client configuration"
244+ )
245+
246+ # Models command
247+ models_parser = subparsers .add_parser (
248+ "models" ,
249+ help = "List and query available models"
250+ )
251+ models_parser .add_argument (
252+ "--info" ,
253+ help = "Get detailed information about a specific model"
254+ )
255+
256+ # Test connection command
257+ test_parser = subparsers .add_parser (
258+ "test-connection" ,
259+ help = "Test connection to Gradient services"
260+ )
261+
262+ # Chat command
263+ chat_parser = subparsers .add_parser (
264+ "chat" ,
265+ help = "Start an interactive chat session"
266+ )
267+ chat_parser .add_argument (
268+ "--model" ,
269+ default = "llama3.3-70b-instruct" ,
270+ help = "Model to use for chat (default: llama3.3-70b-instruct)"
271+ )
272+ chat_parser .add_argument (
273+ "--stream" ,
274+ action = "store_true" ,
275+ help = "Enable streaming responses"
276+ )
277+
278+ args = parser .parse_args ()
279+
280+ if not args .command :
281+ parser .print_help ()
282+ return
283+
284+ # Execute the appropriate command
285+ if args .command == "validate" :
286+ cmd_validate (args )
287+ elif args .command == "models" :
288+ cmd_models (args )
289+ elif args .command == "test-connection" :
290+ cmd_test_connection (args )
291+ elif args .command == "chat" :
292+ cmd_chat (args )
293+
294+
295+ if __name__ == "__main__" :
296+ main ()
0 commit comments