lyceum-cli 1.0.14__tar.gz → 1.0.19__tar.gz

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.
Files changed (32) hide show
  1. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/PKG-INFO +1 -1
  2. lyceum_cli-1.0.19/lyceum/__init__.py +0 -0
  3. lyceum_cli-1.0.19/lyceum/external/__init__.py +0 -0
  4. lyceum_cli-1.0.19/lyceum/external/auth/__init__.py +0 -0
  5. lyceum_cli-1.0.19/lyceum/external/compute/__init__.py +0 -0
  6. lyceum_cli-1.0.19/lyceum/external/compute/execution/__init__.py +0 -0
  7. lyceum_cli-1.0.19/lyceum/external/compute/execution/python.py +99 -0
  8. lyceum_cli-1.0.19/lyceum/external/compute/inference/__init__.py +2 -0
  9. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/lyceum/external/compute/inference/chat.py +30 -4
  10. lyceum_cli-1.0.19/lyceum/external/general/__init__.py +0 -0
  11. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/lyceum/main.py +0 -8
  12. lyceum_cli-1.0.19/lyceum/shared/__init__.py +0 -0
  13. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/lyceum/shared/config.py +7 -8
  14. lyceum_cli-1.0.19/lyceum/shared/display.py +195 -0
  15. lyceum_cli-1.0.19/lyceum/shared/streaming.py +134 -0
  16. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/lyceum_cli.egg-info/PKG-INFO +1 -1
  17. lyceum_cli-1.0.19/lyceum_cli.egg-info/SOURCES.txt +27 -0
  18. lyceum_cli-1.0.19/lyceum_cli.egg-info/top_level.txt +2 -0
  19. lyceum_cli-1.0.19/lyceum_cloud_execution_api_client/__init__.py +0 -0
  20. lyceum_cli-1.0.19/lyceum_cloud_execution_api_client/api/__init__.py +0 -0
  21. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/setup.py +1 -1
  22. lyceum_cli-1.0.14/lyceum/external/compute/inference/__init__.py +0 -5
  23. lyceum_cli-1.0.14/lyceum_cli.egg-info/SOURCES.txt +0 -15
  24. lyceum_cli-1.0.14/lyceum_cli.egg-info/top_level.txt +0 -1
  25. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/lyceum/external/auth/login.py +0 -0
  26. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/lyceum/external/compute/inference/batch.py +0 -0
  27. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/lyceum/external/compute/inference/models.py +0 -0
  28. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/lyceum_cli.egg-info/dependency_links.txt +0 -0
  29. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/lyceum_cli.egg-info/entry_points.txt +0 -0
  30. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/lyceum_cli.egg-info/requires.txt +0 -0
  31. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/lyceum_cloud_execution_api_client/models/__init__.py +0 -0
  32. {lyceum_cli-1.0.14 → lyceum_cli-1.0.19}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lyceum-cli
3
- Version: 1.0.14
3
+ Version: 1.0.19
4
4
  Summary: Command-line interface for Lyceum Cloud Execution API
5
5
  Home-page: https://lyceum.technology
6
6
  Author: Lyceum Team
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,99 @@
1
+ """
2
+ Python execution commands
3
+ """
4
+
5
+ from pathlib import Path
6
+ from typing import Optional
7
+ import typer
8
+ from rich.console import Console
9
+ import httpx
10
+
11
+ from ....shared.config import config
12
+ from ....shared.streaming import stream_execution_output
13
+
14
+ console = Console()
15
+
16
+ python_app = typer.Typer(name="python", help="Python execution commands")
17
+
18
+
19
+ @python_app.command("run")
20
+ def run_python(
21
+ code_or_file: str = typer.Argument(..., help="Python code to execute or path to Python file"),
22
+ machine_type: str = typer.Option("cpu", "--machine", "-m", help="Machine type (cpu, a100, h100, etc.)"),
23
+ timeout: int = typer.Option(60, "--timeout", "-t", help="Execution timeout in seconds"),
24
+ file_name: Optional[str] = typer.Option(None, "--file-name", "-f", help="Name for the execution"),
25
+ requirements: Optional[str] = typer.Option(None, "--requirements", "-r", help="Requirements file path or pip requirements string"),
26
+ imports: Optional[list[str]] = typer.Option(None, "--import", help="Pre-import modules (can be used multiple times)"),
27
+ ):
28
+ """Execute Python code or file on Lyceum Cloud"""
29
+ try:
30
+ # Check if it's a file path
31
+ code_to_execute = code_or_file
32
+ if Path(code_or_file).exists():
33
+ console.print(f"[dim]Reading code from file: {code_or_file}[/dim]")
34
+ with open(code_or_file, 'r') as f:
35
+ code_to_execute = f.read()
36
+ # Use filename as execution name if not provided
37
+ if not file_name:
38
+ file_name = Path(code_or_file).name
39
+
40
+ # Handle requirements
41
+ requirements_content = None
42
+ if requirements:
43
+ # Check if it's a file path
44
+ if Path(requirements).exists():
45
+ console.print(f"[dim]Reading requirements from file: {requirements}[/dim]")
46
+ with open(requirements, 'r') as f:
47
+ requirements_content = f.read()
48
+ else:
49
+ # Treat as direct pip requirements string
50
+ requirements_content = requirements
51
+
52
+ # Create execution request payload
53
+ payload = {
54
+ "code": code_to_execute,
55
+ "nbcode": 0,
56
+ "execution_type": machine_type,
57
+ "timeout": timeout,
58
+ }
59
+
60
+ if file_name:
61
+ payload["file_name"] = file_name
62
+ if requirements_content:
63
+ payload["requirements_content"] = requirements_content
64
+ if imports:
65
+ payload["prior_imports"] = imports
66
+
67
+ # Make API request
68
+ response = httpx.post(
69
+ f"{config.base_url}/api/v2/external/execution/streaming/start",
70
+ headers={"Authorization": f"Bearer {config.api_key}"},
71
+ json=payload,
72
+ timeout=30.0
73
+ )
74
+
75
+ if response.status_code != 200:
76
+ console.print(f"[red]Error: HTTP {response.status_code}[/red]")
77
+ console.print(f"[red]{response.content.decode()}[/red]")
78
+ raise typer.Exit(1)
79
+
80
+ data = response.json()
81
+ execution_id = data['execution_id']
82
+ streaming_url = data.get('streaming_url')
83
+
84
+ console.print(f"[green]✅ Execution started![/green]")
85
+ console.print(f"[dim]Execution ID: {execution_id}[/dim]")
86
+
87
+ if 'pythia_decision' in data:
88
+ console.print(f"[dim]Pythia recommendation: {data['pythia_decision']}[/dim]")
89
+
90
+ # Stream the execution output
91
+ success = stream_execution_output(execution_id, streaming_url)
92
+
93
+ if not success:
94
+ console.print(f"[yellow]💡 You can check the execution later with: lyceum status[/yellow]")
95
+ raise typer.Exit(1)
96
+
97
+ except Exception as e:
98
+ console.print(f"[red]Error: {e}[/red]")
99
+ raise typer.Exit(1)
@@ -0,0 +1,2 @@
1
+ # Empty init - import modules directly in main.py to avoid circular imports
2
+ __all__ = []
@@ -167,24 +167,50 @@ def list_models():
167
167
 
168
168
  @chat_app.command("image")
169
169
  def analyze_image(
170
- image_url: str = typer.Argument(..., help="URL of image to analyze"),
170
+ image_source: str = typer.Argument(..., help="Image URL or path to base64 file"),
171
171
  prompt: str = typer.Option("What do you see in this image?", "--prompt", "-p", help="Question about the image"),
172
- model: str = typer.Option("gpt-4-vision", "--model", "-m", help="Vision model to use"),
172
+ model: str = typer.Option("paddleocr-vl", "--model", "-m", help="Vision model to use"),
173
+ base64: bool = typer.Option(False, "--base64", "-b", help="Treat image_source as path to base64 file"),
173
174
  ):
174
175
  """Analyze an image with AI vision models"""
175
176
  try:
176
177
  client = config.get_client()
177
-
178
+
179
+ # Prepare image data
180
+ image_url = None
181
+ image_data = None
182
+
183
+ if base64:
184
+ # Read base64 from file
185
+ from pathlib import Path
186
+ base64_path = Path(image_source)
187
+ if not base64_path.exists():
188
+ console.print(f"[red]❌ File not found: {image_source}[/red]")
189
+ raise typer.Exit(1)
190
+
191
+ with open(base64_path, 'r') as f:
192
+ image_data = f.read().strip()
193
+
194
+ console.print(f"[dim]📄 Read base64 image from {image_source} ({len(image_data)} chars)[/dim]")
195
+ else:
196
+ # Use as URL
197
+ image_url = image_source
198
+
178
199
  # Create request payload for image analysis
179
200
  sync_request = {
180
201
  "model_id": model,
181
202
  "input": {
182
203
  "text": prompt,
183
- "image_url": image_url
184
204
  },
185
205
  "max_tokens": 1000,
186
206
  "temperature": 0.7
187
207
  }
208
+
209
+ # Add image data
210
+ if image_data:
211
+ sync_request["input"]["image_data"] = image_data
212
+ else:
213
+ sync_request["input"]["image_url"] = image_url
188
214
 
189
215
  console.print(f"[dim]👁️ Analyzing image with {model}...[/dim]")
190
216
 
File without changes
@@ -9,14 +9,10 @@ from rich.console import Console
9
9
 
10
10
  # Import all command modules
11
11
  from .external.auth.login import auth_app
12
- from .external.auth.api_keys import api_keys_app
13
12
  from .external.compute.execution.python import python_app
14
- from .external.compute.execution.docker import docker_app
15
- from .external.compute.execution.workloads import workloads_app
16
13
  from .external.compute.inference.batch import batch_app
17
14
  from .external.compute.inference.chat import chat_app
18
15
  from .external.compute.inference.models import models_app
19
- from .external.general.resources import resources_app
20
16
 
21
17
  app = typer.Typer(
22
18
  name="lyceum",
@@ -28,14 +24,10 @@ console = Console()
28
24
 
29
25
  # Add all command groups
30
26
  app.add_typer(auth_app, name="auth")
31
- app.add_typer(api_keys_app, name="api-keys")
32
27
  app.add_typer(python_app, name="python")
33
- app.add_typer(docker_app, name="docker")
34
- app.add_typer(workloads_app, name="workloads")
35
28
  app.add_typer(batch_app, name="batch")
36
29
  app.add_typer(chat_app, name="chat")
37
30
  app.add_typer(models_app, name="models")
38
- app.add_typer(resources_app, name="resources")
39
31
 
40
32
  # Legacy aliases for backward compatibility
41
33
 
File without changes
@@ -17,7 +17,8 @@ from supabase import create_client
17
17
  import sys
18
18
  sys.path.insert(0, str(Path(__file__).parent.parent.parent / "lyceum-cloud-execution-api-client"))
19
19
 
20
- from lyceum_cloud_execution_api_client.client import AuthenticatedClient
20
+ # Commented out - using httpx directly instead
21
+ # from lyceum_cloud_execution_api_client.client import AuthenticatedClient
21
22
 
22
23
  console = Console()
23
24
 
@@ -122,23 +123,21 @@ class Config:
122
123
  console.print(f"[yellow]⚠️ Token refresh error: {e}[/yellow]")
123
124
  return False
124
125
 
125
- def get_client(self) -> AuthenticatedClient:
126
+ def get_client(self):
126
127
  """Get authenticated API client with automatic token refresh"""
127
128
  if not self.api_key:
128
129
  console.print("[red]Error: Not authenticated. Run 'lyceum login' first.[/red]")
129
130
  raise typer.Exit(1)
130
-
131
+
131
132
  # Check if token is expired and try to refresh
132
133
  if self.is_token_expired():
133
134
  console.print("[dim]🔄 Token expired, attempting refresh...[/dim]")
134
135
  if not self.refresh_access_token():
135
136
  console.print("[red]❌ Token refresh failed. Please run 'lyceum login' again.[/red]")
136
137
  raise typer.Exit(1)
137
-
138
- return AuthenticatedClient(
139
- base_url=self.base_url,
140
- token=self.api_key
141
- )
138
+
139
+ # Return config instance - commands use httpx directly
140
+ return self
142
141
 
143
142
 
144
143
  # Global config instance
@@ -0,0 +1,195 @@
1
+ """
2
+ Display utilities for CLI output formatting
3
+ """
4
+
5
+ from rich.table import Table
6
+ from datetime import datetime
7
+ from typing import Optional
8
+
9
+
10
+ def create_table(title: str, columns: list[tuple[str, str]]) -> Table:
11
+ """
12
+ Create a Rich table with the given title and columns.
13
+
14
+ Args:
15
+ title: Table title
16
+ columns: List of (column_name, style) tuples
17
+
18
+ Returns:
19
+ Rich Table instance
20
+ """
21
+ table = Table(title=title)
22
+ for col_name, style in columns:
23
+ table.add_column(col_name, style=style)
24
+ return table
25
+
26
+
27
+ def format_timestamp(timestamp: str | int | datetime, relative: bool = False) -> str:
28
+ """
29
+ Format a timestamp for display.
30
+
31
+ Args:
32
+ timestamp: Unix timestamp (int/float), ISO string, or datetime object
33
+ relative: If True, show relative time (e.g., "2 hours ago")
34
+
35
+ Returns:
36
+ Formatted timestamp string
37
+ """
38
+ try:
39
+ # Convert to datetime if needed
40
+ if isinstance(timestamp, (int, float)):
41
+ dt = datetime.fromtimestamp(timestamp)
42
+ elif isinstance(timestamp, str):
43
+ # Try parsing ISO format
44
+ dt = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
45
+ elif isinstance(timestamp, datetime):
46
+ dt = timestamp
47
+ else:
48
+ return str(timestamp)
49
+
50
+ if relative:
51
+ # Calculate relative time
52
+ now = datetime.now(dt.tzinfo) if dt.tzinfo else datetime.now()
53
+ diff = now - dt
54
+
55
+ seconds = diff.total_seconds()
56
+ if seconds < 60:
57
+ return f"{int(seconds)}s ago"
58
+ elif seconds < 3600:
59
+ return f"{int(seconds / 60)}m ago"
60
+ elif seconds < 86400:
61
+ return f"{int(seconds / 3600)}h ago"
62
+ elif seconds < 604800:
63
+ return f"{int(seconds / 86400)}d ago"
64
+ else:
65
+ return dt.strftime("%Y-%m-%d")
66
+ else:
67
+ # Return absolute time
68
+ return dt.strftime("%Y-%m-%d %H:%M:%S")
69
+
70
+ except Exception:
71
+ return str(timestamp)
72
+
73
+
74
+ def truncate_id(id_str: str, length: int = 8) -> str:
75
+ """
76
+ Truncate an ID string for display.
77
+
78
+ Args:
79
+ id_str: The ID string to truncate
80
+ length: Number of characters to keep from the start
81
+
82
+ Returns:
83
+ Truncated ID string
84
+ """
85
+ if not id_str:
86
+ return ""
87
+
88
+ if len(id_str) <= length:
89
+ return id_str
90
+
91
+ return f"{id_str[:length]}..."
92
+
93
+
94
+ def format_file_size(bytes: int) -> str:
95
+ """
96
+ Format file size in human-readable format.
97
+
98
+ Args:
99
+ bytes: Size in bytes
100
+
101
+ Returns:
102
+ Formatted size string (e.g., "1.5 MB")
103
+ """
104
+ for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
105
+ if bytes < 1024.0:
106
+ return f"{bytes:.1f} {unit}"
107
+ bytes /= 1024.0
108
+ return f"{bytes:.1f} PB"
109
+
110
+
111
+ def format_duration(seconds: float) -> str:
112
+ """
113
+ Format duration in human-readable format.
114
+
115
+ Args:
116
+ seconds: Duration in seconds
117
+
118
+ Returns:
119
+ Formatted duration string (e.g., "2h 15m 30s")
120
+ """
121
+ if seconds < 60:
122
+ return f"{seconds:.1f}s"
123
+
124
+ minutes = int(seconds / 60)
125
+ secs = int(seconds % 60)
126
+
127
+ if minutes < 60:
128
+ return f"{minutes}m {secs}s"
129
+
130
+ hours = int(minutes / 60)
131
+ mins = int(minutes % 60)
132
+
133
+ if hours < 24:
134
+ return f"{hours}h {mins}m"
135
+
136
+ days = int(hours / 24)
137
+ hrs = int(hours % 24)
138
+
139
+ return f"{days}d {hrs}h"
140
+
141
+
142
+ def status_color(status: str) -> str:
143
+ """
144
+ Get color for status display.
145
+
146
+ Args:
147
+ status: Status string
148
+
149
+ Returns:
150
+ Color name for Rich formatting
151
+ """
152
+ status_lower = status.lower()
153
+
154
+ if status_lower in ['completed', 'success', 'running']:
155
+ return 'green'
156
+ elif status_lower in ['failed', 'error', 'failed_user', 'failed_system']:
157
+ return 'red'
158
+ elif status_lower in ['pending', 'queued', 'in_progress', 'validating', 'finalizing']:
159
+ return 'yellow'
160
+ elif status_lower in ['cancelled', 'expired', 'timeout']:
161
+ return 'dim'
162
+ else:
163
+ return 'white'
164
+
165
+
166
+ def status_emoji(status: str) -> str:
167
+ """
168
+ Get emoji for status display.
169
+
170
+ Args:
171
+ status: Status string
172
+
173
+ Returns:
174
+ Emoji character
175
+ """
176
+ status_lower = status.lower()
177
+
178
+ if status_lower in ['completed', 'success']:
179
+ return '✅'
180
+ elif status_lower in ['failed', 'error', 'failed_user', 'failed_system']:
181
+ return '❌'
182
+ elif status_lower in ['running', 'in_progress']:
183
+ return '🔄'
184
+ elif status_lower in ['pending', 'queued']:
185
+ return '⏳'
186
+ elif status_lower in ['validating']:
187
+ return '🔍'
188
+ elif status_lower in ['finalizing']:
189
+ return '📦'
190
+ elif status_lower in ['cancelled']:
191
+ return '🛑'
192
+ elif status_lower in ['expired', 'timeout']:
193
+ return '⏰'
194
+ else:
195
+ return '⚪'
@@ -0,0 +1,134 @@
1
+ """
2
+ Streaming utilities for execution output
3
+ """
4
+
5
+ import json
6
+ import re
7
+ import httpx
8
+ from rich.console import Console
9
+
10
+ from .config import config
11
+
12
+ console = Console()
13
+
14
+
15
+ def strip_ansi_codes(text: str) -> str:
16
+ """Remove ANSI escape codes from text"""
17
+ ansi_escape = re.compile(r'\x1b\[[0-9;]*m')
18
+ return ansi_escape.sub('', text)
19
+
20
+
21
+ def stream_execution_output(execution_id: str, streaming_url: str = None) -> bool:
22
+ """Stream execution output in real-time. Returns True if successful, False if failed."""
23
+ if not streaming_url:
24
+ # Fallback to old endpoint if no streaming URL provided
25
+ stream_url = f"{config.base_url}/api/v2/external/execution/streaming/{execution_id}"
26
+ else:
27
+ stream_url = streaming_url
28
+
29
+ try:
30
+ console.print(f"[dim]🔗 Connecting to execution stream...[/dim]")
31
+ console.print(f"[dim]Stream URL: {stream_url}[/dim]")
32
+
33
+ with httpx.stream("GET", stream_url, headers={"Authorization": f"Bearer {config.api_key}"}, timeout=600.0) as response:
34
+ if response.status_code != 200:
35
+ console.print(f"[red]❌ Stream failed: HTTP {response.status_code}[/red]")
36
+ return False
37
+
38
+ console.print("[dim]📡 Streaming output...[/dim]")
39
+
40
+ for line in response.iter_lines():
41
+ if line.strip():
42
+ # Parse Server-Sent Events format
43
+ if line.startswith("data: "):
44
+ data_json = line[6:] # Remove "data: " prefix
45
+ try:
46
+ data = json.loads(data_json)
47
+ event_type = data.get("type", "unknown")
48
+
49
+ if event_type == "output":
50
+ # Print output without extra formatting, stripping ANSI codes
51
+ output = data.get("content", "") # Fixed: server sends "content" not "output"
52
+ if output:
53
+ clean_output = strip_ansi_codes(output)
54
+ console.print(clean_output, end="")
55
+
56
+ elif event_type == "completed":
57
+ status = data.get("status", "unknown")
58
+ exec_time = data.get("execution_time", 0)
59
+
60
+ if status == "completed":
61
+ console.print(f"\n[green]✅ Execution completed successfully in {exec_time:.1f}s[/green]")
62
+ elif status in ["failed_user", "failed_system"]:
63
+ console.print(f"\n[red]❌ Execution failed: {status}[/red]")
64
+ # Show errors if available
65
+ errors = data.get("errors")
66
+ if errors:
67
+ console.print(f"[red]Error: {errors}[/red]")
68
+ elif status == "timeout":
69
+ console.print(f"\n[yellow]⏰ Execution timed out after {exec_time:.1f}s[/yellow]")
70
+ elif status == "cancelled":
71
+ console.print(f"\n[yellow]🛑 Execution was cancelled[/yellow]")
72
+
73
+ return status == "completed"
74
+
75
+ elif event_type == "error":
76
+ error_msg = data.get("message", "Unknown error")
77
+ console.print(f"\n[red]❌ Error: {error_msg}[/red]")
78
+ return False
79
+
80
+ except json.JSONDecodeError:
81
+ # Skip malformed JSON
82
+ continue
83
+
84
+ console.print(f"\n[yellow]⚠️ Stream ended without completion signal[/yellow]")
85
+ # Fallback: poll execution status
86
+ return check_execution_status(execution_id)
87
+
88
+ except Exception as e:
89
+ console.print(f"\n[red]❌ Streaming error: {e}[/red]")
90
+ # Fallback: poll execution status
91
+ return check_execution_status(execution_id)
92
+
93
+
94
+ def check_execution_status(execution_id: str) -> bool:
95
+ """Check execution status as fallback when streaming fails."""
96
+ import time
97
+
98
+ console.print("[dim]⏳ Checking execution status...[/dim]")
99
+
100
+ for _ in range(30): # Poll for up to 30 seconds
101
+ try:
102
+ response = httpx.get(
103
+ f"{config.base_url}/api/v2/external/execution/streaming/{execution_id}/status",
104
+ headers={"Authorization": f"Bearer {config.api_key}"},
105
+ timeout=10.0
106
+ )
107
+
108
+ if response.status_code == 200:
109
+ data = response.json()
110
+ status = data.get('status', 'unknown')
111
+
112
+ if status == 'completed':
113
+ console.print(f"[green]✅ Execution completed successfully![/green]")
114
+ return True
115
+ elif status in ['failed_user', 'failed_system', 'failed']:
116
+ console.print(f"[red]❌ Execution failed: {status}[/red]")
117
+ errors = data.get('errors')
118
+ if errors:
119
+ console.print(f"[red]Error: {errors}[/red]")
120
+ return False
121
+ elif status in ['timeout', 'cancelled']:
122
+ console.print(f"[yellow]⚠️ Execution {status}[/yellow]")
123
+ return False
124
+ elif status in ['running', 'pending', 'queued']:
125
+ # Still running, continue polling
126
+ time.sleep(1)
127
+ continue
128
+
129
+ except Exception as e:
130
+ console.print(f"[red]Error checking status: {e}[/red]")
131
+ break
132
+
133
+ console.print("[yellow]⚠️ Status check timed out[/yellow]")
134
+ return False
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lyceum-cli
3
- Version: 1.0.14
3
+ Version: 1.0.19
4
4
  Summary: Command-line interface for Lyceum Cloud Execution API
5
5
  Home-page: https://lyceum.technology
6
6
  Author: Lyceum Team
@@ -0,0 +1,27 @@
1
+ setup.py
2
+ lyceum/__init__.py
3
+ lyceum/main.py
4
+ lyceum/external/__init__.py
5
+ lyceum/external/auth/__init__.py
6
+ lyceum/external/auth/login.py
7
+ lyceum/external/compute/__init__.py
8
+ lyceum/external/compute/execution/__init__.py
9
+ lyceum/external/compute/execution/python.py
10
+ lyceum/external/compute/inference/__init__.py
11
+ lyceum/external/compute/inference/batch.py
12
+ lyceum/external/compute/inference/chat.py
13
+ lyceum/external/compute/inference/models.py
14
+ lyceum/external/general/__init__.py
15
+ lyceum/shared/__init__.py
16
+ lyceum/shared/config.py
17
+ lyceum/shared/display.py
18
+ lyceum/shared/streaming.py
19
+ lyceum_cli.egg-info/PKG-INFO
20
+ lyceum_cli.egg-info/SOURCES.txt
21
+ lyceum_cli.egg-info/dependency_links.txt
22
+ lyceum_cli.egg-info/entry_points.txt
23
+ lyceum_cli.egg-info/requires.txt
24
+ lyceum_cli.egg-info/top_level.txt
25
+ lyceum_cloud_execution_api_client/__init__.py
26
+ lyceum_cloud_execution_api_client/api/__init__.py
27
+ lyceum_cloud_execution_api_client/models/__init__.py
@@ -0,0 +1,2 @@
1
+ lyceum
2
+ lyceum_cloud_execution_api_client
@@ -15,7 +15,7 @@ if readme_file.exists():
15
15
 
16
16
  setup(
17
17
  name="lyceum-cli",
18
- version="1.0.14",
18
+ version="1.0.19",
19
19
  description="Command-line interface for Lyceum Cloud Execution API",
20
20
  long_description=long_description,
21
21
  long_description_content_type="text/markdown",
@@ -1,5 +0,0 @@
1
- from .chat import chat_app
2
- from .batch import batch_app
3
- from .models import models_app
4
-
5
- __all__ = ["chat_app", "batch_app", "models_app"]
@@ -1,15 +0,0 @@
1
- setup.py
2
- lyceum/main.py
3
- lyceum/external/auth/login.py
4
- lyceum/external/compute/inference/__init__.py
5
- lyceum/external/compute/inference/batch.py
6
- lyceum/external/compute/inference/chat.py
7
- lyceum/external/compute/inference/models.py
8
- lyceum/shared/config.py
9
- lyceum_cli.egg-info/PKG-INFO
10
- lyceum_cli.egg-info/SOURCES.txt
11
- lyceum_cli.egg-info/dependency_links.txt
12
- lyceum_cli.egg-info/entry_points.txt
13
- lyceum_cli.egg-info/requires.txt
14
- lyceum_cli.egg-info/top_level.txt
15
- lyceum_cloud_execution_api_client/models/__init__.py
File without changes