lyceum-cli 1.0.19__py3-none-any.whl → 1.0.21__py3-none-any.whl

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.
@@ -86,13 +86,10 @@ class CallbackHandler(BaseHTTPRequestHandler):
86
86
  <p class="text-sm text-gray-500">Your Lyceum CLI has been authenticated successfully and is ready to use.</p>
87
87
  </div>
88
88
 
89
- <!-- Close Button -->
90
- <button
91
- onclick="window.close()"
92
- class="w-full py-2 px-4 bg-blue-600 text-white rounded-md hover:bg-blue-700 focus:ring-2 focus:ring-blue-500 transition-colors"
93
- >
94
- Close Tab
95
- </button>
89
+ <!-- Close Message -->
90
+ <div class="w-full py-3 px-4 bg-gray-50 text-gray-700 rounded-md border border-gray-200">
91
+ You can close this window now
92
+ </div>
96
93
 
97
94
  <!-- Lyceum Branding -->
98
95
  <div class="mt-8 pt-6 border-t border-gray-200">
@@ -160,13 +157,10 @@ class CallbackHandler(BaseHTTPRequestHandler):
160
157
  <p class="text-gray-600">Please try again or contact support if the issue persists.</p>
161
158
  </div>
162
159
 
163
- <!-- Close Button -->
164
- <button
165
- onclick="window.close()"
166
- class="w-full py-2 px-4 bg-gray-600 text-white rounded-md hover:bg-gray-700 focus:ring-2 focus:ring-gray-500 transition-colors"
167
- >
168
- Close Tab
169
- </button>
160
+ <!-- Close Message -->
161
+ <div class="w-full py-3 px-4 bg-gray-50 text-gray-700 rounded-md border border-gray-200">
162
+ You can close this window now
163
+ </div>
170
164
 
171
165
  <!-- Lyceum Branding -->
172
166
  <div class="mt-8 pt-6 border-t border-gray-200">
@@ -209,7 +203,9 @@ class CallbackHandler(BaseHTTPRequestHandler):
209
203
  </div>
210
204
  <h1 class="text-2xl font-bold text-gray-900 mb-2">Invalid Parameters</h1>
211
205
  <p class="text-gray-600 mb-8">The authentication callback received invalid parameters.</p>
212
- <button onclick="window.close()" class="w-full py-2 px-4 bg-gray-600 text-white rounded-md hover:bg-gray-700 focus:ring-2 focus:ring-gray-500 transition-colors">Close Tab</button>
206
+ <div class="w-full py-3 px-4 bg-gray-50 text-gray-700 rounded-md border border-gray-200">
207
+ You can close this window now
208
+ </div>
213
209
  </div>
214
210
  </div>
215
211
  </body>
@@ -244,7 +240,9 @@ class CallbackHandler(BaseHTTPRequestHandler):
244
240
  </div>
245
241
  <h1 class="text-2xl font-bold text-gray-900 mb-2">Page Not Found</h1>
246
242
  <p class="text-gray-600 mb-8">The requested page could not be found.</p>
247
- <button onclick="window.close()" class="w-full py-2 px-4 bg-gray-600 text-white rounded-md hover:bg-gray-700 focus:ring-2 focus:ring-gray-500 transition-colors">Close Tab</button>
243
+ <div class="w-full py-3 px-4 bg-gray-50 text-gray-700 rounded-md border border-gray-200">
244
+ You can close this window now
245
+ </div>
248
246
  </div>
249
247
  </div>
250
248
  </body>
@@ -285,7 +283,9 @@ class CallbackHandler(BaseHTTPRequestHandler):
285
283
  <div class="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-md mb-8">
286
284
  <p class="text-sm">{e}</p>
287
285
  </div>
288
- <button onclick="window.close()" class="w-full py-2 px-4 bg-gray-600 text-white rounded-md hover:bg-gray-700 focus:ring-2 focus:ring-gray-500 transition-colors">Close Tab</button>
286
+ <div class="w-full py-3 px-4 bg-gray-50 text-gray-700 rounded-md border border-gray-200">
287
+ You can close this window now
288
+ </div>
289
289
  </div>
290
290
  </div>
291
291
  </body>
@@ -400,16 +400,32 @@ def login(
400
400
  try:
401
401
  import httpx
402
402
  headers = {"Authorization": f"Bearer {config.api_key}"}
403
- response = httpx.get(f"{config.base_url}/api/v2/external/machine-types", headers=headers, timeout=10.0)
404
- if response.status_code == 200:
405
- console.print("[green]✅ Successfully authenticated![/green]")
406
- if callback_result.get("user"):
407
- console.print(f"[dim]Logged in as: {callback_result['user']}[/dim]")
408
- else:
409
- console.print(f"[red]❌ Token validation failed: HTTP {response.status_code}[/red]")
410
- raise typer.Exit(1)
403
+
404
+ # Create client with explicit timeout and SSL verification
405
+ client = httpx.Client(timeout=30.0, verify=True)
406
+ try:
407
+ response = client.get(
408
+ f"{config.base_url}/api/v2/external/machine-types",
409
+ headers=headers
410
+ )
411
+ if response.status_code == 200:
412
+ console.print("[green]✅ Successfully authenticated![/green]")
413
+ if callback_result.get("user"):
414
+ console.print(f"[dim]Logged in as: {callback_result['user']}[/dim]")
415
+ else:
416
+ console.print(f"[red]❌ Token validation failed: HTTP {response.status_code}[/red]")
417
+ console.print(f"[dim]Response: {response.text}[/dim]")
418
+ raise typer.Exit(1)
419
+ finally:
420
+ client.close()
421
+ except httpx.TimeoutException as e:
422
+ console.print(f"[yellow]⚠️ Token validation timed out: {e}[/yellow]")
423
+ console.print(f"[yellow]Token saved but couldn't verify connectivity to {config.base_url}[/yellow]")
424
+ console.print("[dim]You can test the connection later with 'lyceum auth status'[/dim]")
425
+ # Don't exit with error - token was received successfully
411
426
  except Exception as e:
412
427
  console.print(f"[red]❌ Token validation failed: {e}[/red]")
428
+ console.print(f"[dim]Token saved but couldn't verify. Error type: {type(e).__name__}[/dim]")
413
429
  raise typer.Exit(1)
414
430
 
415
431
  elif callback_result["error"]:
@@ -167,58 +167,34 @@ def list_models():
167
167
 
168
168
  @chat_app.command("image")
169
169
  def analyze_image(
170
- image_source: str = typer.Argument(..., help="Image URL or path to base64 file"),
170
+ image_url: str = typer.Argument(..., help="URL of image to analyze"),
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("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"),
172
+ model: str = typer.Option("gpt-4-vision", "--model", "-m", help="Vision model to use"),
173
+ raw_output: bool = typer.Option(False, "--raw", help="Return full model response instead of just content"),
174
174
  ):
175
175
  """Analyze an image with AI vision models"""
176
176
  try:
177
177
  client = config.get_client()
178
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
-
199
179
  # Create request payload for image analysis
200
180
  sync_request = {
201
181
  "model_id": model,
202
182
  "input": {
203
183
  "text": prompt,
184
+ "image_url": image_url
204
185
  },
205
186
  "max_tokens": 1000,
206
- "temperature": 0.7
187
+ "temperature": 0.7,
188
+ "raw_output": raw_output
207
189
  }
208
190
 
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
214
-
215
191
  console.print(f"[dim]👁️ Analyzing image with {model}...[/dim]")
216
-
192
+
217
193
  import httpx
218
-
194
+
219
195
  url = f"{config.base_url}/api/v2/external/sync/"
220
196
  headers = {"Authorization": f"Bearer {config.api_key}", "Content-Type": "application/json"}
221
-
197
+
222
198
  with httpx.Client() as http_client:
223
199
  response = http_client.post(
224
200
  url,
@@ -226,13 +202,17 @@ def analyze_image(
226
202
  headers=headers,
227
203
  timeout=60.0
228
204
  )
229
-
205
+
230
206
  if response.status_code == 200:
231
207
  result = response.json()
232
-
233
- console.print(f"[green]✅ Image Analysis:[/green]")
234
- console.print(f"[cyan]{result['output']}[/cyan]")
235
-
208
+
209
+ if raw_output:
210
+ console.print(f"[green]✅ Raw Response:[/green]")
211
+ console.print(json.dumps(result.get('raw_response', result['output']), indent=2))
212
+ else:
213
+ console.print(f"[green]✅ Image Analysis:[/green]")
214
+ console.print(f"[cyan]{result['output']}[/cyan]")
215
+
236
216
  elif response.status_code == 503:
237
217
  console.print(f"[red]❌ Vision model {model} is not running.[/red]")
238
218
  raise typer.Exit(1)
@@ -240,7 +220,7 @@ def analyze_image(
240
220
  console.print(f"[red]❌ Error: HTTP {response.status_code}[/red]")
241
221
  console.print(f"[red]{response.text}[/red]")
242
222
  raise typer.Exit(1)
243
-
223
+
244
224
  except Exception as e:
245
225
  console.print(f"[red]❌ Error: {e}[/red]")
246
226
  raise typer.Exit(1)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: lyceum-cli
3
- Version: 1.0.19
3
+ Version: 1.0.21
4
4
  Summary: Command-line interface for Lyceum Cloud Execution API
5
5
  Home-page: https://lyceum.technology
6
6
  Author: Lyceum Team
@@ -2,13 +2,13 @@ lyceum/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  lyceum/main.py,sha256=GO__4_w7Xrr2M6sUlgtG5VK6q64Ako-Qm1i5tcuYk2U,934
3
3
  lyceum/external/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  lyceum/external/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- lyceum/external/auth/login.py,sha256=GYhvhQrWG49LYsqxfNdVfs59GQtjKOlRmcytww9PCWk,23289
5
+ lyceum/external/auth/login.py,sha256=f3_SqrFkKULqeh-08RvkjIoancK_r0PLT_bUv0j3o30,23981
6
6
  lyceum/external/compute/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
7
7
  lyceum/external/compute/execution/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
8
  lyceum/external/compute/execution/python.py,sha256=IiQpudxLAD4lMaQsvON6MGPNGYtEW9Zoip9dSv8KI0g,3745
9
9
  lyceum/external/compute/inference/__init__.py,sha256=4YLoUKDEzitexynJv_Q5O0w1lty8CJ6uyRxuc1LiaBw,89
10
10
  lyceum/external/compute/inference/batch.py,sha256=OHwJndqvsQx0K0-3to8Tc9HB2xA6iq1MNvXvpMxi5Oc,11775
11
- lyceum/external/compute/inference/chat.py,sha256=Dx7HssW3cCRftcWo7eXZ6VHEVBcHNTODdX-Q9NepRoU,9668
11
+ lyceum/external/compute/inference/chat.py,sha256=2axUQIBDEypd-maF3YBcRixvSUsSZHy11dwUZEfU4a4,9040
12
12
  lyceum/external/compute/inference/models.py,sha256=VVHMUhTPVhLKiuvC9Q1zvBD-lM4KDJPUqTmFO7kHpUA,10319
13
13
  lyceum/external/general/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
14
  lyceum/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -18,8 +18,8 @@ lyceum/shared/streaming.py,sha256=-_MLgrACwe1oU5n3UG4kzg9TcUQXc3cLNV6WyplEc_k,60
18
18
  lyceum_cloud_execution_api_client/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  lyceum_cloud_execution_api_client/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
20
  lyceum_cloud_execution_api_client/models/__init__.py,sha256=AMlb9R9O9aNC9hvKz_8TFpEfOolYC3VtFS5JX17kYks,4888
21
- lyceum_cli-1.0.19.dist-info/METADATA,sha256=1aNxetYl8dR0qpQSNK05hTLS2fdTmoCLwdaeu93D8V8,1482
22
- lyceum_cli-1.0.19.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
- lyceum_cli-1.0.19.dist-info/entry_points.txt,sha256=Oq-9wDkxVd6MHgNiUTYwXI9SGhvR3VkD7Mvk0xhiUZo,43
24
- lyceum_cli-1.0.19.dist-info/top_level.txt,sha256=CR7FEMloAXgLsHUR6ti3mWNcpgje27HRHSfq8doIils,41
25
- lyceum_cli-1.0.19.dist-info/RECORD,,
21
+ lyceum_cli-1.0.21.dist-info/METADATA,sha256=ApYPJu1bZmjtTLrathUse4H7vXIs0ywIi7Tns88ZIf0,1482
22
+ lyceum_cli-1.0.21.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
+ lyceum_cli-1.0.21.dist-info/entry_points.txt,sha256=Oq-9wDkxVd6MHgNiUTYwXI9SGhvR3VkD7Mvk0xhiUZo,43
24
+ lyceum_cli-1.0.21.dist-info/top_level.txt,sha256=CR7FEMloAXgLsHUR6ti3mWNcpgje27HRHSfq8doIils,41
25
+ lyceum_cli-1.0.21.dist-info/RECORD,,