gitarsenal-cli 1.5.4 → 1.5.5

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitarsenal-cli",
3
- "version": "1.5.4",
3
+ "version": "1.5.5",
4
4
  "description": "CLI tool for creating Modal sandboxes with GitHub repositories",
5
5
  "main": "index.js",
6
6
  "bin": {
@@ -343,10 +343,6 @@ def call_openai_for_debug(command, error_output, api_key=None, current_dir=None,
343
343
  print(f"šŸ” DEBUG: Current directory: {current_dir}")
344
344
  print(f"šŸ” DEBUG: Sandbox available: {sandbox is not None}")
345
345
  print(f"šŸ” DEBUG: API key provided: {'Yes' if api_key else 'No'}")
346
- if api_key:
347
- print(f"šŸ” DEBUG: API key value: {api_key}")
348
- else:
349
- print(f"šŸ” DEBUG: API key from environment: {os.environ.get('OPENAI_API_KEY')}")
350
346
 
351
347
  # Define _to_str function locally to avoid NameError
352
348
  def _to_str(maybe_bytes):
@@ -692,9 +688,9 @@ Do not provide any explanations, just the exact command to run.
692
688
  def try_api_call(model_name, retries=2, backoff_factor=1.5):
693
689
  print(f"šŸ” DEBUG: Attempting API call with model: {model_name}")
694
690
  print(f"šŸ” DEBUG: API key available: {'Yes' if api_key else 'No'}")
695
- if api_key:
696
- print(f"šŸ” DEBUG: API key length: {len(api_key)}")
697
- print(f"šŸ” DEBUG: API key starts with: {api_key[:10]}...")
691
+ # if api_key:
692
+ # print(f"šŸ” DEBUG: API key length: {len(api_key)}")
693
+ # print(f"šŸ” DEBUG: API key starts with: {api_key[:10]}...")
698
694
 
699
695
  payload = {
700
696
  "model": model_name,
@@ -1,145 +0,0 @@
1
- # Modal Proxy Service for GitArsenal CLI
2
-
3
- This document explains how to set up and use the Modal proxy service with GitArsenal CLI.
4
-
5
- ## What is the Modal Proxy Service?
6
-
7
- The Modal proxy service allows users to access Modal services (like GPU-accelerated containers) without exposing the owner's Modal token. The service runs on a server and provides API endpoints for creating sandboxes and SSH containers, using API key authentication.
8
-
9
- ## Server-Side Setup
10
-
11
- 1. **Install Requirements**:
12
- ```bash
13
- pip install flask flask-cors modal python-dotenv
14
- ```
15
-
16
- 2. **Set Environment Variables**:
17
- Create a `.env` file in the same directory as `modal_proxy_service.py`:
18
- ```
19
- MODAL_TOKEN=your_modal_token_here
20
- ADMIN_KEY=your_admin_key_here
21
- API_KEYS=optional_comma_separated_list_of_api_keys
22
- ```
23
-
24
- 3. **Start the Service**:
25
- ```bash
26
- python modal_proxy_service.py
27
- ```
28
-
29
- The service will start on port 5001 by default.
30
-
31
- 4. **Create an API Key** (if not pre-configured in `.env`):
32
- ```bash
33
- curl -X POST http://localhost:5001/api/create-api-key \
34
- -H "X-Admin-Key: your_admin_key_here"
35
- ```
36
-
37
- This will return a JSON response with a new API key:
38
- ```json
39
- {"api_key": "generated_api_key_here"}
40
- ```
41
-
42
- 5. **Optional: Use ngrok to expose the service publicly**:
43
- ```bash
44
- ngrok http 5001
45
- ```
46
-
47
- This will provide you with a public URL that you can share with users.
48
-
49
- Current ngrok URL: `https://932ffd63ad3d.ngrok-free.app`
50
-
51
- ## Client-Side Setup
52
-
53
- 1. **Configure the proxy client**:
54
- ```bash
55
- ./gitarsenal.py proxy configure
56
- ```
57
-
58
- You'll be prompted to enter:
59
- - The proxy URL (the default is now set to `https://932ffd63ad3d.ngrok-free.app`)
60
- - Your API key
61
-
62
- 2. **Check proxy service status**:
63
- ```bash
64
- ./gitarsenal.py proxy status
65
- ```
66
-
67
- ## Using the Proxy Service
68
-
69
- ### Create an SSH Container
70
-
71
- ```bash
72
- # Using the proxy command
73
- ./gitarsenal.py proxy ssh --gpu A10G --repo-url https://github.com/username/repo.git --wait
74
-
75
- # Or using the standard ssh command with --use-proxy flag
76
- ./gitarsenal.py ssh --use-proxy --gpu A10G --repo-url https://github.com/username/repo.git
77
- ```
78
-
79
- ### Create a Sandbox
80
-
81
- ```bash
82
- # Using the proxy command
83
- ./gitarsenal.py proxy sandbox --gpu A10G --repo-url https://github.com/username/repo.git --wait
84
-
85
- # Or using the standard sandbox command with --use-proxy flag
86
- ./gitarsenal.py sandbox --use-proxy --gpu A10G --repo-url https://github.com/username/repo.git
87
- ```
88
-
89
- ## Troubleshooting
90
-
91
- ### "Token missing" Error
92
-
93
- If you see a "Token missing" error when creating containers through the proxy service:
94
-
95
- 1. **Check that the MODAL_TOKEN is set on the server**:
96
- - Verify the `.env` file has a valid MODAL_TOKEN
97
- - Ensure the token is correctly formatted and not expired
98
- - Restart the proxy service after updating the token
99
-
100
- 2. **Manually set the token on the server**:
101
- ```bash
102
- # On the server running the proxy service
103
- export MODAL_TOKEN_ID=your_modal_token_here
104
- modal token set your_modal_token_here
105
- ```
106
-
107
- 3. **Verify the token works directly on the server**:
108
- ```bash
109
- # Test if the token works by listing Modal volumes
110
- modal volume list
111
- ```
112
-
113
- 4. **Check the proxy service logs**:
114
- - Look at `modal_proxy.log` on the server for detailed error messages
115
- - Check for messages like "Modal token verification failed"
116
- - Ensure the token is being properly passed to the Modal API
117
-
118
- 5. **Restart the proxy service**:
119
- ```bash
120
- # Kill the existing process and restart
121
- pkill -f modal_proxy_service.py
122
- python modal_proxy_service.py
123
- ```
124
-
125
- 6. **Check ngrok connection**:
126
- - Verify the ngrok tunnel is active and the URL is correct
127
- - Ensure requests are being properly forwarded to the proxy service
128
-
129
- ### "Unauthorized" Error
130
-
131
- If you see an "Unauthorized" error:
132
-
133
- 1. **When creating an API key**:
134
- - Make sure you're including the correct admin key in the request header
135
- - Example: `-H "X-Admin-Key: your_admin_key_here"`
136
-
137
- 2. **When using the API**:
138
- - Make sure your client is configured with a valid API key
139
- - Reconfigure with `./gitarsenal.py proxy configure`
140
-
141
- ## Security Considerations
142
-
143
- - Keep your admin key and API keys secure
144
- - Use HTTPS if exposing the service publicly (ngrok provides this automatically)
145
- - Consider implementing additional authentication mechanisms for production use
package/python/README.md DELETED
@@ -1,68 +0,0 @@
1
- # GitArsenal CLI Python Modules
2
-
3
- This directory contains Python modules for the GitArsenal CLI.
4
-
5
- ## Modal Integration
6
-
7
- The GitArsenal CLI integrates with Modal for creating sandboxes and SSH containers. The following modules are available:
8
-
9
- - `modal_proxy_service.py`: A proxy service for Modal operations
10
- - `test_modalSandboxScript.py`: Creates Modal sandboxes and SSH containers
11
- - `setup_modal_token.py`: Sets up the Modal token in the environment
12
- - `fetch_modal_tokens.py`: Fetches Modal tokens from the proxy server
13
-
14
- ## Security Features
15
-
16
- ### Modal Token Cleanup
17
-
18
- For enhanced security, GitArsenal CLI now automatically cleans up Modal tokens after SSH containers are created. This ensures that your Modal token is not left in the environment or on disk after the container is started.
19
-
20
- The cleanup process:
21
- 1. Removes Modal token environment variables (MODAL_TOKEN_ID, MODAL_TOKEN, MODAL_TOKEN_SECRET)
22
- 2. Deletes the ~/.modal.toml file which contains the authentication token
23
- 3. Runs automatically after SSH container creation
24
- 4. Runs on service shutdown via signal handlers
25
-
26
- This simple but effective approach prevents potential token leakage when containers are shared or when the service is stopped, and ensures that users cannot continue to use Modal CLI commands like `modal shell` after the container is created.
27
-
28
- ## Usage
29
-
30
- To use the GitArsenal CLI Python modules, you can import them directly or use the provided scripts.
31
-
32
- ### Creating a Modal SSH Container
33
-
34
- ```python
35
- from test_modalSandboxScript import create_modal_ssh_container
36
-
37
- result = create_modal_ssh_container(
38
- gpu_type="A10G",
39
- repo_url="https://github.com/user/repo",
40
- repo_name="repo",
41
- setup_commands=["pip install -r requirements.txt"],
42
- timeout_minutes=60
43
- )
44
-
45
- # The Modal token is automatically cleaned up after the container is created
46
- ```
47
-
48
- ### Running the Modal Proxy Service
49
-
50
- ```bash
51
- python modal_proxy_service.py
52
- ```
53
-
54
- The service will automatically clean up Modal tokens on shutdown.
55
-
56
- ## Testing
57
-
58
- To test the Modal token cleanup functionality:
59
-
60
- ```bash
61
- python test_token_cleanup.py
62
- ```
63
-
64
- This script verifies that the token cleanup process works correctly by:
65
- 1. Setting up a test Modal token
66
- 2. Verifying the token exists in environment and files
67
- 3. Cleaning up the token
68
- 4. Verifying the token has been removed
@@ -1,71 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Fix commands for Modal SSH container
4
- This script fixes common issues with commands in the Modal SSH container
5
- """
6
-
7
- import os
8
- import sys
9
- import subprocess
10
-
11
- def fix_command(cmd):
12
- """Fix common issues with commands"""
13
- # Replace 'source' with '.' for sh shell
14
- if 'source' in cmd:
15
- cmd = cmd.replace('source', '.')
16
- print(f"āœ… Fixed: Replaced 'source' with '.' for sh shell")
17
-
18
- # Fix uv venv and activation in one command
19
- if 'uv venv' in cmd and '&&' in cmd:
20
- # The command is already trying to create and activate a venv
21
- # Just need to make sure 'source' is replaced with '.'
22
- pass
23
-
24
- # Fix uv pip install without active venv
25
- if 'uv pip install' in cmd and 'venv' not in cmd:
26
- # Create and activate a venv first
27
- cmd = f"uv venv .venv && . .venv/bin/activate && {cmd}"
28
- print(f"āœ… Fixed: Added venv creation and activation before pip install")
29
-
30
- return cmd
31
-
32
- def run_fixed_command(cmd):
33
- """Run the fixed command"""
34
- fixed_cmd = fix_command(cmd)
35
- print(f"\nšŸ”§ Running fixed command: {fixed_cmd}")
36
-
37
- # Run the command
38
- result = subprocess.run(fixed_cmd, shell=True, text=True, capture_output=True)
39
-
40
- # Print the output
41
- if result.stdout:
42
- print(f"\n--- Output ---\n{result.stdout}")
43
- if result.stderr:
44
- print(f"\n--- Error ---\n{result.stderr}")
45
-
46
- # Return the result
47
- return result.returncode == 0
48
-
49
- def main():
50
- """Main function"""
51
- if len(sys.argv) < 2:
52
- print("Usage: python fix_commands.py 'command to fix'")
53
- return 1
54
-
55
- # Get the command from command line
56
- cmd = ' '.join(sys.argv[1:])
57
- print(f"šŸ” Original command: {cmd}")
58
-
59
- # Run the fixed command
60
- success = run_fixed_command(cmd)
61
-
62
- # Print the result
63
- if success:
64
- print("\nāœ… Command executed successfully")
65
- else:
66
- print("\nāŒ Command failed")
67
-
68
- return 0 if success else 1
69
-
70
- if __name__ == "__main__":
71
- sys.exit(main())
@@ -1,58 +0,0 @@
1
- def get_setup_commands_from_local_api(repo_url, gitingest_data):
2
- """Try to get setup commands from the API."""
3
- # Use only online endpoints
4
- api_endpoints = [
5
- "https://www.gitarsenal.dev/api/analyze-with-gitingest" # Working endpoint with www prefix
6
- ]
7
-
8
- # Prepare the request payload
9
- payload = {
10
- "repoUrl": repo_url,
11
- "gitingestData": gitingest_data,
12
- "userRequest": "Setup and run the repository"
13
- }
14
-
15
- # Try each API endpoint
16
- for api_url in api_endpoints:
17
- # Use the retry mechanism for more reliable requests
18
- response = make_api_request_with_retry(
19
- url=api_url,
20
- payload=payload,
21
- max_retries=2,
22
- timeout=180 # 3 minute timeout
23
- )
24
-
25
- if response and response.status_code == 200:
26
- try:
27
- data = response.json()
28
- print(f"šŸ“„ Response size: {len(response.text)} bytes")
29
- print(f"šŸ“„ Response URL: {response.url}")
30
- if "setupInstructions" in data and "commands" in data["setupInstructions"]:
31
- commands = data["setupInstructions"]["commands"]
32
- print(f"āœ… Successfully fetched {len(commands)} setup commands from API at {api_url}")
33
-
34
- # Print the original commands
35
- print("šŸ“‹ Original commands from API:")
36
- for i, cmd in enumerate(commands, 1):
37
- print(f" {i}. {cmd}")
38
-
39
- # Fix the commands
40
- fixed_commands = fix_setup_commands(commands)
41
-
42
- # Print the fixed commands
43
- print("\nšŸ“‹ Fixed commands:")
44
- for i, cmd in enumerate(fixed_commands, 1):
45
- print(f" {i}. {cmd}")
46
-
47
- return fixed_commands
48
- else:
49
- print("āš ļø API response did not contain setupInstructions.commands field")
50
- except json.JSONDecodeError:
51
- print(f"āŒ Failed to parse API response as JSON")
52
- elif response:
53
- print(f"āŒ API request failed with status code: {response.status_code}")
54
- else:
55
- print(f"āŒ Failed to connect to {api_url}")
56
-
57
- print("āŒ All API endpoints failed")
58
- return None
@@ -1,119 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- GitArsenal Credentials Manager CLI
4
-
5
- This script allows users to manage their API keys and tokens for GitArsenal CLI.
6
- """
7
-
8
- import argparse
9
- import sys
10
- from credentials_manager import CredentialsManager
11
-
12
- def main():
13
- parser = argparse.ArgumentParser(description="Manage credentials for GitArsenal CLI")
14
- subparsers = parser.add_subparsers(dest="command", help="Command to run")
15
-
16
- # Setup command
17
- setup_parser = subparsers.add_parser("setup", help="Set up all credentials")
18
-
19
- # Set command
20
- set_parser = subparsers.add_parser("set", help="Set a specific credential")
21
- set_parser.add_argument("key", choices=["openai_api_key", "modal_token", "huggingface_token", "wandb_api_key"],
22
- help="The credential to set")
23
-
24
- # Get command
25
- get_parser = subparsers.add_parser("get", help="Get a specific credential")
26
- get_parser.add_argument("key", choices=["openai_api_key", "modal_token", "huggingface_token", "wandb_api_key"],
27
- help="The credential to get")
28
-
29
- # Clear command
30
- clear_parser = subparsers.add_parser("clear", help="Clear credentials")
31
- clear_parser.add_argument("key", nargs="?", choices=["openai_api_key", "modal_token", "huggingface_token", "wandb_api_key", "all"],
32
- default="all", help="The credential to clear (default: all)")
33
-
34
- # List command
35
- list_parser = subparsers.add_parser("list", help="List all saved credentials (shows only existence, not values)")
36
-
37
- args = parser.parse_args()
38
-
39
- # Create credentials manager
40
- credentials_manager = CredentialsManager()
41
-
42
- if args.command == "setup":
43
- print("šŸ“‹ Setting up all credentials for GitArsenal CLI")
44
- print("You'll be prompted for each credential. Press Ctrl+C to skip any credential.")
45
-
46
- try:
47
- # OpenAI API key
48
- print("\nšŸ”‘ Setting up OpenAI API key")
49
- credentials_manager.get_openai_api_key()
50
-
51
- # Modal token
52
- print("\nšŸ”‘ Setting up Modal token")
53
- credentials_manager.get_modal_token()
54
-
55
- # Hugging Face token
56
- print("\nšŸ”‘ Setting up Hugging Face token")
57
- credentials_manager.get_huggingface_token()
58
-
59
- # Weights & Biases API key
60
- print("\nšŸ”‘ Setting up Weights & Biases API key")
61
- credentials_manager.get_wandb_api_key()
62
-
63
- print("\nāœ… Credentials setup complete!")
64
-
65
- except KeyboardInterrupt:
66
- print("\n\nāš ļø Setup interrupted. Some credentials may not have been set.")
67
- return 1
68
-
69
- elif args.command == "set":
70
- print(f"šŸ”‘ Setting {args.key}")
71
- if args.key == "openai_api_key":
72
- credentials_manager.get_openai_api_key()
73
- elif args.key == "modal_token":
74
- credentials_manager.get_modal_token()
75
- elif args.key == "huggingface_token":
76
- credentials_manager.get_huggingface_token()
77
- elif args.key == "wandb_api_key":
78
- credentials_manager.get_wandb_api_key()
79
-
80
- elif args.command == "get":
81
- credentials = credentials_manager.load_credentials()
82
- if args.key in credentials:
83
- # Show only first and last few characters for security
84
- value = credentials[args.key]
85
- masked_value = value[:4] + "*" * (len(value) - 8) + value[-4:] if len(value) > 8 else "****"
86
- print(f"{args.key}: {masked_value}")
87
- else:
88
- print(f"āŒ {args.key} not found in saved credentials")
89
- return 1
90
-
91
- elif args.command == "clear":
92
- if args.key == "all":
93
- credentials_manager.clear_all_credentials()
94
- print("āœ… All credentials cleared")
95
- else:
96
- if credentials_manager.clear_credential(args.key):
97
- print(f"āœ… {args.key} cleared")
98
- else:
99
- print(f"āŒ {args.key} not found in saved credentials")
100
- return 1
101
-
102
- elif args.command == "list":
103
- credentials = credentials_manager.load_credentials()
104
- if not credentials:
105
- print("No credentials saved")
106
- return 0
107
-
108
- print("šŸ“‹ Saved credentials:")
109
- for key in credentials:
110
- print(f"- {key}: {'*' * 8}")
111
-
112
- else:
113
- parser.print_help()
114
- return 1
115
-
116
- return 0
117
-
118
- if __name__ == "__main__":
119
- sys.exit(main())
@@ -1,75 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Patch the test_modalSandboxScript.py file to fix issues with LLM debugging
4
- """
5
-
6
- import os
7
- import sys
8
- import re
9
-
10
- def read_file(filename):
11
- """Read a file and return its contents"""
12
- with open(filename, 'r') as f:
13
- return f.read()
14
-
15
- def write_file(filename, content):
16
- """Write content to a file"""
17
- with open(filename, 'w') as f:
18
- f.write(content)
19
-
20
- def patch_file(filename):
21
- """Patch the file to fix issues with LLM debugging"""
22
- print(f"šŸ”§ Patching {filename}...")
23
-
24
- # Read the file
25
- content = read_file(filename)
26
-
27
- # Make a backup
28
- backup_filename = f"{filename}.bak"
29
- write_file(backup_filename, content)
30
- print(f"āœ… Created backup: {backup_filename}")
31
-
32
- # Fix 1: Replace 'source' with '.' in commands
33
- pattern1 = r'(uv venv.*?)source(.*?activate)'
34
- replacement1 = r'\1.\2'
35
- content = re.sub(pattern1, replacement1, content)
36
- print("āœ… Fixed 'source' commands")
37
-
38
- # Fix 2: Add environment activation before uv pip commands
39
- pattern2 = r'(uv pip install.*?)(?!\. .*?activate)'
40
- replacement2 = r'. openr1/bin/activate && \1'
41
- content = re.sub(pattern2, replacement2, content)
42
- print("āœ… Added environment activation before pip commands")
43
-
44
- # Write the patched file
45
- write_file(filename, content)
46
- print(f"āœ… Patched file written: {filename}")
47
-
48
- return True
49
-
50
- def main():
51
- """Main function"""
52
- # Get the file to patch
53
- if len(sys.argv) > 1:
54
- filename = sys.argv[1]
55
- else:
56
- # Default to the test_modalSandboxScript.py in the current directory
57
- filename = "test_modalSandboxScript.py"
58
-
59
- # Check if the file exists
60
- if not os.path.exists(filename):
61
- print(f"āŒ File not found: {filename}")
62
- return 1
63
-
64
- # Patch the file
65
- success = patch_file(filename)
66
-
67
- if success:
68
- print("\nāœ… Patching completed successfully")
69
- return 0
70
- else:
71
- print("\nāŒ Patching failed")
72
- return 1
73
-
74
- if __name__ == "__main__":
75
- sys.exit(main())
@@ -1,47 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Run With Modal Token - Wrapper Script
4
-
5
- This script sets up the Modal token in the environment and then runs a specified command.
6
- It's useful for running commands that need Modal authentication without modifying them.
7
-
8
- Usage:
9
- python run_with_modal_token.py <command> [args...]
10
-
11
- Example:
12
- python run_with_modal_token.py python modal_proxy_service.py
13
- """
14
-
15
- import os
16
- import sys
17
- import subprocess
18
- from setup_modal_token import setup_modal_token
19
-
20
- def main():
21
- # Set up Modal token (should always succeed with built-in token)
22
- setup_modal_token()
23
- print("āœ… Using built-in Modal token for freemium service")
24
-
25
- # Check if a command was provided
26
- if len(sys.argv) < 2:
27
- print("āŒ No command provided")
28
- print(f"Usage: {sys.argv[0]} <command> [args...]")
29
- sys.exit(1)
30
-
31
- # Get the command and arguments
32
- cmd = sys.argv[1]
33
- args = sys.argv[2:]
34
-
35
- # Print what we're about to run
36
- print(f"šŸš€ Running command with Modal token: {cmd} {' '.join(args)}")
37
-
38
- # Run the command
39
- try:
40
- result = subprocess.run([cmd] + args)
41
- sys.exit(result.returncode)
42
- except Exception as e:
43
- print(f"āŒ Error running command: {e}")
44
- sys.exit(1)
45
-
46
- if __name__ == "__main__":
47
- main()
@@ -1,55 +0,0 @@
1
- #!/usr/bin/env python3
2
- """
3
- Test importing and using get_tokens from fetch_modal_tokens
4
- """
5
-
6
- import os
7
- import sys
8
-
9
- def main():
10
- """Main function to test importing and using get_tokens"""
11
- print("šŸ” Testing import of get_tokens from fetch_modal_tokens...")
12
-
13
- # Set a test API key for the script to use
14
- os.environ["GITARSENAL_API_KEY"] = "test_key"
15
-
16
- try:
17
- # Import the function
18
- from fetch_modal_tokens import get_tokens
19
- print("āœ… Successfully imported get_tokens from fetch_modal_tokens")
20
-
21
- # Call the function
22
- print("šŸ”„ Calling get_tokens()...")
23
- token_id, token_secret = get_tokens()
24
-
25
- # Check the results
26
- print("āœ… Successfully called get_tokens()")
27
- print(f" token_id: {token_id[:5]}...{token_id[-5:]}")
28
- print(f" token_secret: {token_secret[:5]}...{token_secret[-5:]}")
29
-
30
- # Check if environment variables were set
31
- if os.environ.get("MODAL_TOKEN_ID") == token_id:
32
- print("āœ… MODAL_TOKEN_ID environment variable set correctly")
33
- else:
34
- print("āŒ MODAL_TOKEN_ID environment variable not set correctly")
35
-
36
- if os.environ.get("MODAL_TOKEN_SECRET") == token_secret:
37
- print("āœ… MODAL_TOKEN_SECRET environment variable set correctly")
38
- else:
39
- print("āŒ MODAL_TOKEN_SECRET environment variable not set correctly")
40
-
41
- # Check if OPENAI_API_KEY was set
42
- if os.environ.get("OPENAI_API_KEY"):
43
- print("āœ… OPENAI_API_KEY environment variable set")
44
- print(f" length: {len(os.environ.get('OPENAI_API_KEY'))}")
45
- else:
46
- print("āŒ OPENAI_API_KEY environment variable not set")
47
-
48
- return True
49
- except Exception as e:
50
- print(f"āŒ Error: {e}")
51
- return False
52
-
53
- if __name__ == "__main__":
54
- success = main()
55
- sys.exit(0 if success else 1)