skypilot-nightly 1.0.0.dev20250424__py3-none-any.whl → 1.0.0.dev20250426__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.
Files changed (36) hide show
  1. sky/__init__.py +2 -2
  2. sky/adaptors/aws.py +57 -4
  3. sky/adaptors/common.py +2 -1
  4. sky/adaptors/kubernetes.py +14 -9
  5. sky/cli.py +1 -1
  6. sky/client/cli.py +1 -1
  7. sky/client/sdk.py +7 -4
  8. sky/clouds/aws.py +3 -4
  9. sky/clouds/gcp.py +28 -12
  10. sky/clouds/runpod.py +14 -5
  11. sky/clouds/service_catalog/data_fetchers/fetch_aws.py +3 -2
  12. sky/clouds/service_catalog/runpod_catalog.py +0 -10
  13. sky/dashboard/out/404.html +1 -1
  14. sky/dashboard/out/clusters/[cluster]/[job].html +1 -1
  15. sky/dashboard/out/clusters/[cluster].html +1 -1
  16. sky/dashboard/out/clusters.html +1 -1
  17. sky/dashboard/out/index.html +1 -1
  18. sky/dashboard/out/jobs/[job].html +1 -1
  19. sky/dashboard/out/jobs.html +1 -1
  20. sky/data/storage.py +4 -4
  21. sky/exceptions.py +5 -0
  22. sky/jobs/server/core.py +31 -3
  23. sky/provision/aws/config.py +30 -11
  24. sky/provision/aws/instance.py +24 -10
  25. sky/provision/runpod/instance.py +17 -14
  26. sky/provision/runpod/utils.py +4 -2
  27. sky/server/common.py +25 -4
  28. sky/templates/runpod-ray.yml.j2 +1 -0
  29. {skypilot_nightly-1.0.0.dev20250424.dist-info → skypilot_nightly-1.0.0.dev20250426.dist-info}/METADATA +1 -1
  30. {skypilot_nightly-1.0.0.dev20250424.dist-info → skypilot_nightly-1.0.0.dev20250426.dist-info}/RECORD +36 -36
  31. /sky/dashboard/out/_next/static/{MqmRhu1oPMgLy6v25hibm → WO8lTFPfj-lO3_gDGEiN8}/_buildManifest.js +0 -0
  32. /sky/dashboard/out/_next/static/{MqmRhu1oPMgLy6v25hibm → WO8lTFPfj-lO3_gDGEiN8}/_ssgManifest.js +0 -0
  33. {skypilot_nightly-1.0.0.dev20250424.dist-info → skypilot_nightly-1.0.0.dev20250426.dist-info}/WHEEL +0 -0
  34. {skypilot_nightly-1.0.0.dev20250424.dist-info → skypilot_nightly-1.0.0.dev20250426.dist-info}/entry_points.txt +0 -0
  35. {skypilot_nightly-1.0.0.dev20250424.dist-info → skypilot_nightly-1.0.0.dev20250426.dist-info}/licenses/LICENSE +0 -0
  36. {skypilot_nightly-1.0.0.dev20250424.dist-info → skypilot_nightly-1.0.0.dev20250426.dist-info}/top_level.txt +0 -0
sky/__init__.py CHANGED
@@ -5,7 +5,7 @@ from typing import Optional
5
5
  import urllib.request
6
6
 
7
7
  # Replaced with the current commit when building the wheels.
8
- _SKYPILOT_COMMIT_SHA = '3d993746d92a6d4cc8802156663bce1a4bf15b92'
8
+ _SKYPILOT_COMMIT_SHA = '979c123c54d0ee615cd854a586f88afa9cb3d2ce'
9
9
 
10
10
 
11
11
  def _get_git_commit():
@@ -35,7 +35,7 @@ def _get_git_commit():
35
35
 
36
36
 
37
37
  __commit__ = _get_git_commit()
38
- __version__ = '1.0.0.dev20250424'
38
+ __version__ = '1.0.0.dev20250426'
39
39
  __root_dir__ = os.path.dirname(os.path.abspath(__file__))
40
40
 
41
41
 
sky/adaptors/aws.py CHANGED
@@ -31,12 +31,22 @@ This is informed by the following boto3 docs:
31
31
  import logging
32
32
  import threading
33
33
  import time
34
- from typing import Any, Callable
34
+ import typing
35
+ from typing import Callable, Literal, Optional, TypeVar
35
36
 
36
37
  from sky.adaptors import common
37
38
  from sky.utils import annotations
38
39
  from sky.utils import common_utils
39
40
 
41
+ if typing.TYPE_CHECKING:
42
+ import boto3
43
+ _ = boto3 # Supress pylint use before assignment error
44
+ import mypy_boto3_ec2
45
+ import mypy_boto3_iam
46
+ import mypy_boto3_s3
47
+ import mypy_boto3_service_quotas
48
+ import mypy_boto3_sts
49
+
40
50
  _IMPORT_ERROR_MESSAGE = ('Failed to import dependencies for AWS. '
41
51
  'Try pip install "skypilot[aws]"')
42
52
  boto3 = common.LazyImport('boto3', import_error_message=_IMPORT_ERROR_MESSAGE)
@@ -44,6 +54,8 @@ botocore = common.LazyImport('botocore',
44
54
  import_error_message=_IMPORT_ERROR_MESSAGE)
45
55
  _LAZY_MODULES = (boto3, botocore)
46
56
 
57
+ T = TypeVar('T')
58
+
47
59
  logger = logging.getLogger(__name__)
48
60
  _session_creation_lock = threading.RLock()
49
61
 
@@ -73,8 +85,8 @@ def _assert_kwargs_builtin_type(kwargs):
73
85
  f'kwargs should not contain none built-in types: {kwargs}')
74
86
 
75
87
 
76
- def _create_aws_object(creation_fn_or_cls: Callable[[], Any],
77
- object_name: str) -> Any:
88
+ def _create_aws_object(creation_fn_or_cls: Callable[[], T],
89
+ object_name: str) -> T:
78
90
  """Create an AWS object.
79
91
 
80
92
  Args:
@@ -123,6 +135,25 @@ def session(check_credentials: bool = True):
123
135
  return s
124
136
 
125
137
 
138
+ # New typing overloads can be added as needed.
139
+ @typing.overload
140
+ def resource(service_name: Literal['ec2'],
141
+ **kwargs) -> 'mypy_boto3_ec2.ServiceResource':
142
+ ...
143
+
144
+
145
+ @typing.overload
146
+ def resource(service_name: Literal['s3'],
147
+ **kwargs) -> 'mypy_boto3_s3.ServiceResource':
148
+ ...
149
+
150
+
151
+ @typing.overload
152
+ def resource(service_name: Literal['iam'],
153
+ **kwargs) -> 'mypy_boto3_iam.ServiceResource':
154
+ ...
155
+
156
+
126
157
  # Avoid caching the resource/client objects. If we are using the assumed role,
127
158
  # the credentials will be automatically rotated, but the cached resource/client
128
159
  # object will only refresh the credentials with a fixed 15 minutes interval,
@@ -142,7 +173,7 @@ def resource(service_name: str, **kwargs):
142
173
  """
143
174
  _assert_kwargs_builtin_type(kwargs)
144
175
 
145
- max_attempts = kwargs.pop('max_attempts', None)
176
+ max_attempts: Optional[int] = kwargs.pop('max_attempts', None)
146
177
  if max_attempts is not None:
147
178
  config = botocore_config().Config(
148
179
  retries={'max_attempts': max_attempts})
@@ -158,6 +189,28 @@ def resource(service_name: str, **kwargs):
158
189
  service_name, **kwargs), 'resource')
159
190
 
160
191
 
192
+ # New typing overloads can be added as needed.
193
+ @typing.overload
194
+ def client(service_name: Literal['s3'], **kwargs) -> 'mypy_boto3_s3.Client':
195
+ pass
196
+
197
+
198
+ @typing.overload
199
+ def client(service_name: Literal['ec2'], **kwargs) -> 'mypy_boto3_ec2.Client':
200
+ pass
201
+
202
+
203
+ @typing.overload
204
+ def client(service_name: Literal['sts'], **kwargs) -> 'mypy_boto3_sts.Client':
205
+ pass
206
+
207
+
208
+ @typing.overload
209
+ def client(service_name: Literal['service-quotas'],
210
+ **kwargs) -> 'mypy_boto3_service_quotas.Client':
211
+ pass
212
+
213
+
161
214
  def client(service_name: str, **kwargs):
162
215
  """Create an AWS client of a certain service.
163
216
 
sky/adaptors/common.py CHANGED
@@ -2,10 +2,11 @@
2
2
  import functools
3
3
  import importlib
4
4
  import threading
5
+ import types
5
6
  from typing import Any, Callable, Optional, Tuple
6
7
 
7
8
 
8
- class LazyImport:
9
+ class LazyImport(types.ModuleType):
9
10
  """Lazy importer for modules.
10
11
 
11
12
  This is mainly used in two cases:
@@ -70,21 +70,26 @@ def _load_config(context: Optional[str] = None):
70
70
  kubernetes.config.load_kube_config(context=context)
71
71
  except kubernetes.config.config_exception.ConfigException as e:
72
72
  suffix = common_utils.format_exception(e, use_bracket=True)
73
+ context_name = '(current-context)' if context is None else context
73
74
  # Check if exception was due to no current-context
74
75
  if 'Expected key current-context' in str(e):
75
- err_str = (
76
- f'Failed to load Kubernetes configuration for {context!r}. '
77
- 'Kubeconfig does not contain any valid context(s).'
78
- f'\n{suffix}\n'
79
- ' If you were running a local Kubernetes '
80
- 'cluster, run `sky local up` to start the cluster.')
76
+ err_str = ('Failed to load Kubernetes configuration for '
77
+ f'{context_name!r}. '
78
+ 'Kubeconfig does not contain any valid context(s).'
79
+ f'\n{suffix}\n'
80
+ ' If you were running a local Kubernetes '
81
+ 'cluster, run `sky local up` to start the cluster.')
81
82
  else:
82
83
  kubeconfig_path = os.environ.get('KUBECONFIG', '~/.kube/config')
83
84
  err_str = (
84
- f'Failed to load Kubernetes configuration for {context!r}. '
85
- 'Please check if your kubeconfig file exists at '
86
- f'{kubeconfig_path} and is valid.\n{suffix}')
85
+ f'Failed to load Kubernetes configuration for '
86
+ f'{context_name!r}. Please check if your kubeconfig file '
87
+ f'exists at {kubeconfig_path} and is valid.\n{suffix}')
87
88
  err_str += '\nTo disable Kubernetes for SkyPilot: run `sky check`.'
89
+ if context is None: # kubernetes defaults to current-context.
90
+ err_str += (
91
+ '\nHint: Kubernetes attempted to query the current-context '
92
+ 'set in kubeconfig. Check if the current-context is valid.')
88
93
  with ux_utils.print_exception_no_traceback():
89
94
  raise ValueError(err_str) from None
90
95
 
sky/cli.py CHANGED
@@ -5910,7 +5910,7 @@ def api_info():
5910
5910
  api_server_info = sdk.api_info()
5911
5911
  user_name = os.getenv(constants.USER_ENV_VAR, getpass.getuser())
5912
5912
  user_hash = common_utils.get_user_hash()
5913
- dashboard_url = f'{url}/dashboard'
5913
+ dashboard_url = server_common.get_dashboard_url(url)
5914
5914
  click.echo(f'Using SkyPilot API server: {url} Dashboard: {dashboard_url}\n'
5915
5915
  f'{ux_utils.INDENT_SYMBOL}Status: {api_server_info["status"]}, '
5916
5916
  f'commit: {api_server_info["commit"]}, '
sky/client/cli.py CHANGED
@@ -5910,7 +5910,7 @@ def api_info():
5910
5910
  api_server_info = sdk.api_info()
5911
5911
  user_name = os.getenv(constants.USER_ENV_VAR, getpass.getuser())
5912
5912
  user_hash = common_utils.get_user_hash()
5913
- dashboard_url = f'{url}/dashboard'
5913
+ dashboard_url = server_common.get_dashboard_url(url)
5914
5914
  click.echo(f'Using SkyPilot API server: {url} Dashboard: {dashboard_url}\n'
5915
5915
  f'{ux_utils.INDENT_SYMBOL}Status: {api_server_info["status"]}, '
5916
5916
  f'commit: {api_server_info["commit"]}, '
sky/client/sdk.py CHANGED
@@ -301,7 +301,7 @@ def validate(
301
301
  def dashboard() -> None:
302
302
  """Starts the dashboard for SkyPilot."""
303
303
  api_server_url = server_common.get_server_url()
304
- url = f'{api_server_url}/dashboard'
304
+ url = server_common.get_dashboard_url(api_server_url)
305
305
  logger.info(f'Opening dashboard in browser: {url}')
306
306
  webbrowser.open(url)
307
307
 
@@ -1725,9 +1725,11 @@ def api_start(
1725
1725
  if foreground:
1726
1726
  # Explain why current process exited
1727
1727
  logger.info('API server is already running:')
1728
- dashboard_msg = f'Dashboard: {server_common.get_server_url(host)}/dashboard'
1728
+ api_server_url = server_common.get_server_url(host)
1729
+ dashboard_url = server_common.get_dashboard_url(api_server_url)
1730
+ dashboard_msg = f'Dashboard: {dashboard_url}'
1729
1731
  logger.info(f'{ux_utils.INDENT_SYMBOL}SkyPilot API server: '
1730
- f'{server_common.get_server_url(host)} {dashboard_msg}\n'
1732
+ f'{api_server_url} {dashboard_msg}\n'
1731
1733
  f'{ux_utils.INDENT_LAST_SYMBOL}'
1732
1734
  f'View API server logs at: {constants.API_SERVER_LOGS}')
1733
1735
 
@@ -1835,7 +1837,8 @@ def api_login(endpoint: Optional[str] = None) -> None:
1835
1837
  config = skypilot_config.get_user_config()
1836
1838
  config.set_nested(('api_server', 'endpoint'), endpoint)
1837
1839
  common_utils.dump_yaml(str(config_path), dict(config))
1838
- dashboard_msg = f'Dashboard: {endpoint}/dashboard'
1840
+ dashboard_url = server_common.get_dashboard_url(endpoint)
1841
+ dashboard_msg = f'Dashboard: {dashboard_url}'
1839
1842
  click.secho(
1840
1843
  f'Logged in to SkyPilot API server at {endpoint}.'
1841
1844
  f' {dashboard_msg}',
sky/clouds/aws.py CHANGED
@@ -312,13 +312,12 @@ class AWS(clouds.Cloud):
312
312
  'Example: ami-0729d913a335efca7')
313
313
  try:
314
314
  client = aws.client('ec2', region_name=region)
315
- image_info = client.describe_images(ImageIds=[image_id])
316
- image_info = image_info.get('Images', [])
315
+ image_info = client.describe_images(ImageIds=[image_id]).get(
316
+ 'Images', [])
317
317
  if not image_info:
318
318
  with ux_utils.print_exception_no_traceback():
319
319
  raise ValueError(image_not_found_message)
320
- image_info = image_info[0]
321
- image_size = image_info['BlockDeviceMappings'][0]['Ebs'][
320
+ image_size = image_info[0]['BlockDeviceMappings'][0]['Ebs'][
322
321
  'VolumeSize']
323
322
  except (aws.botocore_exceptions().NoCredentialsError,
324
323
  aws.botocore_exceptions().ProfileNotFound):
sky/clouds/gcp.py CHANGED
@@ -174,7 +174,10 @@ class GCP(clouds.Cloud):
174
174
  # Install the Google Cloud SDK:
175
175
  f'{_INDENT_PREFIX} $ pip install google-api-python-client\n'
176
176
  f'{_INDENT_PREFIX} $ conda install -c conda-forge '
177
- 'google-cloud-sdk -y')
177
+ 'google-cloud-sdk -y\n'
178
+ f'{_INDENT_PREFIX} If gcloud was recently installed with wget, API server'
179
+ ' may need to be restarted with following commands:\n'
180
+ f'{_INDENT_PREFIX} $ sky api stop; sky api start')
178
181
 
179
182
  _CREDENTIAL_HINT = (
180
183
  'Run the following commands:\n'
@@ -476,7 +479,7 @@ class GCP(clouds.Cloud):
476
479
  'custom_resources': None,
477
480
  'use_spot': r.use_spot,
478
481
  'gcp_project_id': self.get_project_id(dryrun),
479
- **GCP._get_disk_specs(_failover_disk_tier()),
482
+ **GCP._get_disk_specs(r.instance_type, _failover_disk_tier()),
480
483
  }
481
484
  accelerators = r.accelerators
482
485
  if accelerators is not None:
@@ -776,7 +779,7 @@ class GCP(clouds.Cloud):
776
779
  raise FileNotFoundError(file)
777
780
  except FileNotFoundError as e:
778
781
  return False, (
779
- f'Credentails are not set. '
782
+ f'Credentials are not set. '
780
783
  f'{cls._CREDENTIAL_HINT}\n'
781
784
  f'{cls._INDENT_PREFIX}Details: '
782
785
  f'{common_utils.format_exception(e, use_bracket=True)}')
@@ -1012,20 +1015,23 @@ class GCP(clouds.Cloud):
1012
1015
  if disk_tier != resources_utils.DiskTier.ULTRA or instance_type is None:
1013
1016
  return True, ''
1014
1017
  # Ultra disk tier (pd-extreme) only support m2, m3 and part of n2
1015
- # instance types, so we failover to lower tiers for other instance
1016
- # types. Reference:
1018
+ # instance types. For a3 instances, we map the ULTRA tier to
1019
+ # hyperdisk-balanced. For all other instance types, we failover to
1020
+ # lower tiers. Reference:
1017
1021
  # https://cloud.google.com/compute/docs/disks/extreme-persistent-disk#machine_shape_support # pylint: disable=line-too-long
1018
1022
  series = instance_type.split('-')[0]
1019
- if series in ['m2', 'm3', 'n2']:
1023
+ if series in ['m2', 'm3', 'n2', 'a3']:
1020
1024
  if series == 'n2':
1021
1025
  num_cpus = int(instance_type.split('-')[2])
1022
1026
  if num_cpus < 64:
1023
1027
  return False, ('n2 series with less than 64 vCPUs are '
1024
1028
  'not supported with pd-extreme.')
1025
1029
  return True, ''
1026
- return False, (f'{series} series is not supported with pd-extreme. '
1027
- 'Only m2, m3 series and n2 series with 64 or more vCPUs '
1028
- 'are supported.')
1030
+ return False, (f'{series} series is not supported with pd-extreme '
1031
+ 'or hyperdisk-balanced. Only m2, m3 series and n2 '
1032
+ 'series with 64 or more vCPUs are supported with '
1033
+ 'pd-extreme. Also, only a3 is supported with '
1034
+ 'hyperdisk-balanced.')
1029
1035
 
1030
1036
  @classmethod
1031
1037
  def check_disk_tier_enabled(cls, instance_type: Optional[str],
@@ -1036,7 +1042,7 @@ class GCP(clouds.Cloud):
1036
1042
  raise exceptions.NotSupportedError(msg)
1037
1043
 
1038
1044
  @classmethod
1039
- def _get_disk_type(cls,
1045
+ def _get_disk_type(cls, instance_type: Optional[str],
1040
1046
  disk_tier: Optional[resources_utils.DiskTier]) -> str:
1041
1047
  tier = cls._translate_disk_tier(disk_tier)
1042
1048
  tier2name = {
@@ -1045,13 +1051,23 @@ class GCP(clouds.Cloud):
1045
1051
  resources_utils.DiskTier.MEDIUM: 'pd-balanced',
1046
1052
  resources_utils.DiskTier.LOW: 'pd-standard',
1047
1053
  }
1054
+
1055
+ # Remap series-specific disk types
1056
+ series = instance_type.split('-')[0] # type: ignore
1057
+ if series == 'a3':
1058
+ tier2name[resources_utils.DiskTier.LOW] = tier2name[
1059
+ resources_utils.DiskTier.MEDIUM]
1060
+ tier2name[resources_utils.DiskTier.ULTRA] = 'hyperdisk-balanced'
1061
+
1048
1062
  return tier2name[tier]
1049
1063
 
1050
1064
  @classmethod
1051
1065
  def _get_disk_specs(
1052
- cls,
1066
+ cls, instance_type: Optional[str],
1053
1067
  disk_tier: Optional[resources_utils.DiskTier]) -> Dict[str, Any]:
1054
- specs: Dict[str, Any] = {'disk_tier': cls._get_disk_type(disk_tier)}
1068
+ specs: Dict[str, Any] = {
1069
+ 'disk_tier': cls._get_disk_type(instance_type, disk_tier)
1070
+ }
1055
1071
  if disk_tier == resources_utils.DiskTier.ULTRA:
1056
1072
  # Only pd-extreme supports custom iops.
1057
1073
  # see https://cloud.google.com/compute/docs/disks#disk-types
sky/clouds/runpod.py CHANGED
@@ -67,13 +67,18 @@ class RunPod(clouds.Cloud):
67
67
  accelerators: Optional[Dict[str, int]],
68
68
  use_spot: bool, region: Optional[str],
69
69
  zone: Optional[str]) -> List[clouds.Region]:
70
- assert zone is None, 'RunPod does not support zones.'
71
- del accelerators, zone # unused
70
+ del accelerators # unused
72
71
  regions = service_catalog.get_region_zones_for_instance_type(
73
72
  instance_type, use_spot, 'runpod')
74
73
 
75
74
  if region is not None:
76
75
  regions = [r for r in regions if r.name == region]
76
+
77
+ if zone is not None:
78
+ for r in regions:
79
+ assert r.zones is not None, r
80
+ r.set_zones([z for z in r.zones if z.name == zone])
81
+ regions = [r for r in regions if r.zones]
77
82
  return regions
78
83
 
79
84
  @classmethod
@@ -93,7 +98,7 @@ class RunPod(clouds.Cloud):
93
98
  instance_type: str,
94
99
  accelerators: Optional[Dict[str, int]] = None,
95
100
  use_spot: bool = False,
96
- ) -> Iterator[None]:
101
+ ) -> Iterator[Optional[List['clouds.Zone']]]:
97
102
  del num_nodes # unused
98
103
  regions = cls.regions_with_offering(instance_type,
99
104
  accelerators,
@@ -101,7 +106,7 @@ class RunPod(clouds.Cloud):
101
106
  region=region,
102
107
  zone=None)
103
108
  for r in regions:
104
- assert r.zones is None, r
109
+ assert r
105
110
  yield r.zones
106
111
 
107
112
  def instance_type_to_hourly_cost(self,
@@ -158,7 +163,10 @@ class RunPod(clouds.Cloud):
158
163
  zones: Optional[List['clouds.Zone']],
159
164
  num_nodes: int,
160
165
  dryrun: bool = False) -> Dict[str, Optional[str]]:
161
- del zones, dryrun, cluster_name # unused
166
+ del dryrun, cluster_name # unused
167
+ assert zones is not None, (region, zones)
168
+
169
+ zone_names = [zone.name for zone in zones]
162
170
 
163
171
  r = resources
164
172
  acc_dict = self.get_accelerators_from_instance_type(r.instance_type)
@@ -187,6 +195,7 @@ class RunPod(clouds.Cloud):
187
195
  'instance_type': instance_type,
188
196
  'custom_resources': custom_resources,
189
197
  'region': region.name,
198
+ 'availability_zone': ','.join(zone_names),
190
199
  'image_id': image_id,
191
200
  'use_spot': use_spot,
192
201
  'bid_per_gpu': str(hourly_cost),
@@ -13,7 +13,7 @@ import sys
13
13
  import textwrap
14
14
  import traceback
15
15
  import typing
16
- from typing import Dict, List, Optional, Set, Tuple, Union
16
+ from typing import List, Optional, Set, Tuple, Union
17
17
 
18
18
  import numpy as np
19
19
 
@@ -24,6 +24,7 @@ from sky.utils import log_utils
24
24
  from sky.utils import ux_utils
25
25
 
26
26
  if typing.TYPE_CHECKING:
27
+ from mypy_boto3_ec2 import type_defs as ec2_type_defs
27
28
  import pandas as pd
28
29
  else:
29
30
  pd = adaptors_common.LazyImport('pandas')
@@ -192,7 +193,7 @@ def _get_spot_pricing_table(region: str) -> 'pd.DataFrame':
192
193
  paginator = client.get_paginator('describe_spot_price_history')
193
194
  response_iterator = paginator.paginate(ProductDescriptions=['Linux/UNIX'],
194
195
  StartTime=datetime.datetime.utcnow())
195
- ret: List[Dict[str, str]] = []
196
+ ret: List['ec2_type_defs.SpotPriceTypeDef'] = []
196
197
  for response in response_iterator:
197
198
  # response['SpotPriceHistory'] is a list of dicts, each dict is like:
198
199
  # {
@@ -8,7 +8,6 @@ import typing
8
8
  from typing import Dict, List, Optional, Tuple, Union
9
9
 
10
10
  from sky.clouds.service_catalog import common
11
- from sky.utils import ux_utils
12
11
 
13
12
  if typing.TYPE_CHECKING:
14
13
  from sky.clouds import cloud
@@ -23,9 +22,6 @@ def instance_type_exists(instance_type: str) -> bool:
23
22
  def validate_region_zone(
24
23
  region: Optional[str],
25
24
  zone: Optional[str]) -> Tuple[Optional[str], Optional[str]]:
26
- if zone is not None:
27
- with ux_utils.print_exception_no_traceback():
28
- raise ValueError('RunPod does not support zones.')
29
25
  return common.validate_region_zone_impl('runpod', _df, region, zone)
30
26
 
31
27
 
@@ -34,9 +30,6 @@ def get_hourly_cost(instance_type: str,
34
30
  region: Optional[str] = None,
35
31
  zone: Optional[str] = None) -> float:
36
32
  """Returns the cost, or the cheapest cost among all zones for spot."""
37
- if zone is not None:
38
- with ux_utils.print_exception_no_traceback():
39
- raise ValueError('RunPod does not support zones.')
40
33
  return common.get_hourly_cost_impl(_df, instance_type, use_spot, region,
41
34
  zone)
42
35
 
@@ -69,9 +62,6 @@ def get_instance_type_for_accelerator(
69
62
  region: Optional[str] = None,
70
63
  zone: Optional[str] = None) -> Tuple[Optional[List[str]], List[str]]:
71
64
  """Returns a list of instance types that have the given accelerator."""
72
- if zone is not None:
73
- with ux_utils.print_exception_no_traceback():
74
- raise ValueError('RunPod does not support zones.')
75
65
  return common.get_instance_type_for_accelerator_impl(df=_df,
76
66
  acc_name=acc_name,
77
67
  acc_count=acc_count,
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-1be831200e60c5c0.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"MqmRhu1oPMgLy6v25hibm","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><title>404: This page could not be found</title><meta name="next-head-count" content="3"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_error-1be831200e60c5c0.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;text-align:center;display:flex;flex-direction:column;align-items:center;justify-content:center"><div style="line-height:48px"><style>body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}</style><h1 class="next-error-h1" style="display:inline-block;margin:0 20px 0 0;padding-right:23px;font-size:24px;font-weight:500;vertical-align:top">404</h1><div style="display:inline-block"><h2 style="font-size:14px;font-weight:400;line-height:28px">This page could not be found<!-- -->.</h2></div></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{"statusCode":404}},"page":"/_error","query":{},"buildId":"WO8lTFPfj-lO3_gDGEiN8","assetPrefix":"/dashboard","nextExport":true,"isFallback":false,"gip":true,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/678-206dddca808e6d16.js" defer=""></script><script src="/dashboard/_next/static/chunks/979-7bf73a4c7cea0f5c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D/%5Bjob%5D-6ac338bc2239cb45.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div>Loading...</div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]/[job]","query":{},"buildId":"MqmRhu1oPMgLy6v25hibm","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/678-206dddca808e6d16.js" defer=""></script><script src="/dashboard/_next/static/chunks/979-7bf73a4c7cea0f5c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D/%5Bjob%5D-6ac338bc2239cb45.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div>Loading...</div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]/[job]","query":{},"buildId":"WO8lTFPfj-lO3_gDGEiN8","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/678-206dddca808e6d16.js" defer=""></script><script src="/dashboard/_next/static/chunks/312-c3c8845990db8ffc.js" defer=""></script><script src="/dashboard/_next/static/chunks/979-7bf73a4c7cea0f5c.js" defer=""></script><script src="/dashboard/_next/static/chunks/845-9e60713e0c441abc.js" defer=""></script><script src="/dashboard/_next/static/chunks/236-2db3ee3fba33dd9e.js" defer=""></script><script src="/dashboard/_next/static/chunks/37-0a572fe0dbb89c4d.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D-f383db7389368ea7.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div>Loading...</div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]","query":{},"buildId":"MqmRhu1oPMgLy6v25hibm","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/678-206dddca808e6d16.js" defer=""></script><script src="/dashboard/_next/static/chunks/312-c3c8845990db8ffc.js" defer=""></script><script src="/dashboard/_next/static/chunks/979-7bf73a4c7cea0f5c.js" defer=""></script><script src="/dashboard/_next/static/chunks/845-9e60713e0c441abc.js" defer=""></script><script src="/dashboard/_next/static/chunks/236-2db3ee3fba33dd9e.js" defer=""></script><script src="/dashboard/_next/static/chunks/37-0a572fe0dbb89c4d.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters/%5Bcluster%5D-f383db7389368ea7.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div>Loading...</div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters/[cluster]","query":{},"buildId":"WO8lTFPfj-lO3_gDGEiN8","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><link rel="preload" href="/dashboard/skypilot.svg" as="image" fetchpriority="high"/><meta name="next-head-count" content="3"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/678-206dddca808e6d16.js" defer=""></script><script src="/dashboard/_next/static/chunks/312-c3c8845990db8ffc.js" defer=""></script><script src="/dashboard/_next/static/chunks/979-7bf73a4c7cea0f5c.js" defer=""></script><script src="/dashboard/_next/static/chunks/845-9e60713e0c441abc.js" defer=""></script><script src="/dashboard/_next/static/chunks/37-0a572fe0dbb89c4d.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters-a93b93e10b8b074e.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div class="min-h-screen bg-gray-50"><div class="fixed top-0 left-0 right-0 z-50 shadow-sm"><div class="fixed top-0 left-0 right-0 bg-white z-30 h-14 px-4 border-b border-gray-200 shadow-sm"><div class="flex items-center h-full"><div class="flex items-center space-x-4 mr-6"><a class="flex items-center px-1 pt-1 h-full" href="/dashboard"><div class="h-20 w-20 flex items-center justify-center"><img alt="SkyPilot Logo" fetchpriority="high" width="80" height="80" decoding="async" data-nimg="1" class="w-full h-full object-contain" style="color:transparent" src="/dashboard/skypilot.svg"/></div></a></div><div class="flex items-center space-x-2 md:space-x-6 mr-6"><a class="inline-flex items-center border-b-2 border-transparent text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/clusters"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect><rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect><line x1="6" x2="6.01" y1="6" y2="6"></line><line x1="6" x2="6.01" y1="18" y2="18"></line></svg><span>Clusters</span></a><a class="inline-flex items-center border-b-2 border-transparent hover:text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/jobs"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"></path><rect width="20" height="14" x="2" y="6" rx="2"></rect></svg><span>Jobs</span></a><div class="inline-flex items-center px-1 pt-1 text-gray-400"><svg class="w-4 h-4" viewBox="0 0 423.683 423.683" width="24" height="24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><g><path d="M54.376,287.577h310.459c26.48,0,48.02-13.979,48.02-40.453c0-17.916-10.001-34.07-25.559-42.292 c-19.021-72.951-86.061-125.196-162.002-125.223v-3.431h-3.854V61.814h3.854v-9.569h-31.38v9.569h3.854v14.363h-3.854v3.431 c-75.941,0.026-142.97,52.272-161.988,125.217c-15.56,8.216-25.573,24.376-25.573,42.291 C6.36,273.597,27.896,287.577,54.376,287.577z M47.676,227.145l7.214-2.424l1.617-7.447 c13.884-64.232,71.707-110.862,137.467-110.862h31.274c65.763,0,123.582,46.63,137.473,110.862l1.607,7.447l7.223,2.424 c8.678,2.92,14.506,10.946,14.506,19.979c0,11.703-9.517,13.647-21.221,13.647H54.376c-11.7,0-21.22-1.944-21.22-13.647 C33.162,238.091,38.984,230.065,47.676,227.145z M423.683,334.602v36.836H0v-36.836h25.348v-18.418h372.99v18.418H423.683z"></path></g></g></svg><span class="ml-2">Services</span><span class="text-xs ml-2 px-1.5 py-0.5 bg-gray-100 text-gray-500 rounded">Soon</span></div></div><div class="flex items-center space-x-1 ml-auto"><a href="https://skypilot.readthedocs.io/en/latest/" target="_blank" rel="noopener noreferrer" class="inline-flex items-center px-2 py-1 text-gray-600 hover:text-blue-600 transition-colors duration-150 cursor-pointer" title="Docs"><span class="mr-1">Docs</span><svg class="w-3.5 h-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg></a><div class="border-l border-gray-200 h-6 mx-1"></div><a href="https://github.com/skypilot-org/skypilot" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="GitHub"><svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"></path></svg></a><a href="https://slack.skypilot.co/" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="Slack"><svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path transform="scale(0.85) translate(1.8, 1.8)" d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z"></path></svg></a><a href="https://github.com/skypilot-org/skypilot/issues/new" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="Leave Feedback"><svg class="w-5 h-5" stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g><path fill="none" d="M0 0h24v24H0z"></path><path d="M6.455 19L2 22.5V4a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H6.455zM4 18.385L5.763 17H20V5H4v13.385zM11 13h2v2h-2v-2zm0-6h2v5h-2V7z"></path></g></svg></a></div></div></div></div><div class="transition-all duration-200 ease-in-out min-h-screen" style="padding-top:56px"><main class="p-6"><div class="flex items-center justify-between mb-4 h-5"><div class="text-base"><a class="text-sky-blue hover:underline leading-none" href="/dashboard/clusters">Sky Clusters</a></div><div class="flex items-center"><button class="justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 hover:bg-accent h-10 px-4 py-2 text-sky-blue hover:text-sky-blue-bright flex items-center"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw h-4 w-4 mr-1.5"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg><span>Refresh</span></button></div></div><div><div class="rounded-lg border bg-card text-card-foreground shadow-sm"><div class="relative w-full overflow-auto"><table class="w-full caption-bottom text-base"><thead class="[&amp;_tr]:border-b"><tr class="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted"><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">Status</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">Cluster</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">User</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">Resources</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">Region</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">Started</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0">Actions</th></tr></thead><tbody class="[&amp;_tr:last-child]:border-0"><tr class="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted"><td class="p-4 align-middle [&amp;:has([role=checkbox])]:pr-0 text-center py-6 text-gray-500" colSpan="8">No active clusters</td></tr></tbody></table></div></div></div></main></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters","query":{},"buildId":"MqmRhu1oPMgLy6v25hibm","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><link rel="preload" href="/dashboard/skypilot.svg" as="image" fetchpriority="high"/><meta name="next-head-count" content="3"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/678-206dddca808e6d16.js" defer=""></script><script src="/dashboard/_next/static/chunks/312-c3c8845990db8ffc.js" defer=""></script><script src="/dashboard/_next/static/chunks/979-7bf73a4c7cea0f5c.js" defer=""></script><script src="/dashboard/_next/static/chunks/845-9e60713e0c441abc.js" defer=""></script><script src="/dashboard/_next/static/chunks/37-0a572fe0dbb89c4d.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/clusters-a93b93e10b8b074e.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div class="min-h-screen bg-gray-50"><div class="fixed top-0 left-0 right-0 z-50 shadow-sm"><div class="fixed top-0 left-0 right-0 bg-white z-30 h-14 px-4 border-b border-gray-200 shadow-sm"><div class="flex items-center h-full"><div class="flex items-center space-x-4 mr-6"><a class="flex items-center px-1 pt-1 h-full" href="/dashboard"><div class="h-20 w-20 flex items-center justify-center"><img alt="SkyPilot Logo" fetchpriority="high" width="80" height="80" decoding="async" data-nimg="1" class="w-full h-full object-contain" style="color:transparent" src="/dashboard/skypilot.svg"/></div></a></div><div class="flex items-center space-x-2 md:space-x-6 mr-6"><a class="inline-flex items-center border-b-2 border-transparent text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/clusters"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="8" x="2" y="2" rx="2" ry="2"></rect><rect width="20" height="8" x="2" y="14" rx="2" ry="2"></rect><line x1="6" x2="6.01" y1="6" y2="6"></line><line x1="6" x2="6.01" y1="18" y2="18"></line></svg><span>Clusters</span></a><a class="inline-flex items-center border-b-2 border-transparent hover:text-blue-600 px-1 pt-1 space-x-2" href="/dashboard/jobs"><svg class="w-4 h-4" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 20V4a2 2 0 0 0-2-2h-4a2 2 0 0 0-2 2v16"></path><rect width="20" height="14" x="2" y="6" rx="2"></rect></svg><span>Jobs</span></a><div class="inline-flex items-center px-1 pt-1 text-gray-400"><svg class="w-4 h-4" viewBox="0 0 423.683 423.683" width="24" height="24" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" fill="currentColor" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><g id="SVGRepo_bgCarrier" stroke-width="0"></g><g id="SVGRepo_tracerCarrier" stroke-linecap="round" stroke-linejoin="round"></g><g id="SVGRepo_iconCarrier"><g><path d="M54.376,287.577h310.459c26.48,0,48.02-13.979,48.02-40.453c0-17.916-10.001-34.07-25.559-42.292 c-19.021-72.951-86.061-125.196-162.002-125.223v-3.431h-3.854V61.814h3.854v-9.569h-31.38v9.569h3.854v14.363h-3.854v3.431 c-75.941,0.026-142.97,52.272-161.988,125.217c-15.56,8.216-25.573,24.376-25.573,42.291 C6.36,273.597,27.896,287.577,54.376,287.577z M47.676,227.145l7.214-2.424l1.617-7.447 c13.884-64.232,71.707-110.862,137.467-110.862h31.274c65.763,0,123.582,46.63,137.473,110.862l1.607,7.447l7.223,2.424 c8.678,2.92,14.506,10.946,14.506,19.979c0,11.703-9.517,13.647-21.221,13.647H54.376c-11.7,0-21.22-1.944-21.22-13.647 C33.162,238.091,38.984,230.065,47.676,227.145z M423.683,334.602v36.836H0v-36.836h25.348v-18.418h372.99v18.418H423.683z"></path></g></g></svg><span class="ml-2">Services</span><span class="text-xs ml-2 px-1.5 py-0.5 bg-gray-100 text-gray-500 rounded">Soon</span></div></div><div class="flex items-center space-x-1 ml-auto"><a href="https://skypilot.readthedocs.io/en/latest/" target="_blank" rel="noopener noreferrer" class="inline-flex items-center px-2 py-1 text-gray-600 hover:text-blue-600 transition-colors duration-150 cursor-pointer" title="Docs"><span class="mr-1">Docs</span><svg class="w-3.5 h-3.5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path><polyline points="15 3 21 3 21 9"></polyline><line x1="10" y1="14" x2="21" y2="3"></line></svg></a><div class="border-l border-gray-200 h-6 mx-1"></div><a href="https://github.com/skypilot-org/skypilot" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="GitHub"><svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"></path></svg></a><a href="https://slack.skypilot.co/" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="Slack"><svg class="w-5 h-5" xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="currentColor"><path transform="scale(0.85) translate(1.8, 1.8)" d="M5.042 15.165a2.528 2.528 0 0 1-2.52 2.523A2.528 2.528 0 0 1 0 15.165a2.527 2.527 0 0 1 2.522-2.52h2.52v2.52zM6.313 15.165a2.527 2.527 0 0 1 2.521-2.52 2.527 2.527 0 0 1 2.521 2.52v6.313A2.528 2.528 0 0 1 8.834 24a2.528 2.528 0 0 1-2.521-2.522v-6.313zM8.834 5.042a2.528 2.528 0 0 1-2.521-2.52A2.528 2.528 0 0 1 8.834 0a2.528 2.528 0 0 1 2.521 2.522v2.52H8.834zM8.834 6.313a2.528 2.528 0 0 1 2.521 2.521 2.528 2.528 0 0 1-2.521 2.521H2.522A2.528 2.528 0 0 1 0 8.834a2.528 2.528 0 0 1 2.522-2.521h6.312zM18.956 8.834a2.528 2.528 0 0 1 2.522-2.521A2.528 2.528 0 0 1 24 8.834a2.528 2.528 0 0 1-2.522 2.521h-2.522V8.834zM17.688 8.834a2.528 2.528 0 0 1-2.523 2.521 2.527 2.527 0 0 1-2.52-2.521V2.522A2.527 2.527 0 0 1 15.165 0a2.528 2.528 0 0 1 2.523 2.522v6.312zM15.165 18.956a2.528 2.528 0 0 1 2.523 2.522A2.528 2.528 0 0 1 15.165 24a2.527 2.527 0 0 1-2.52-2.522v-2.522h2.52zM15.165 17.688a2.527 2.527 0 0 1-2.52-2.523 2.526 2.526 0 0 1 2.52-2.52h6.313A2.527 2.527 0 0 1 24 15.165a2.528 2.528 0 0 1-2.522 2.523h-6.313z"></path></svg></a><a href="https://github.com/skypilot-org/skypilot/issues/new" target="_blank" rel="noopener noreferrer" class="inline-flex items-center justify-center p-2 rounded-full text-gray-600 hover:bg-gray-100 transition-colors duration-150 cursor-pointer" title="Leave Feedback"><svg class="w-5 h-5" stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><g><path fill="none" d="M0 0h24v24H0z"></path><path d="M6.455 19L2 22.5V4a1 1 0 0 1 1-1h18a1 1 0 0 1 1 1v14a1 1 0 0 1-1 1H6.455zM4 18.385L5.763 17H20V5H4v13.385zM11 13h2v2h-2v-2zm0-6h2v5h-2V7z"></path></g></svg></a></div></div></div></div><div class="transition-all duration-200 ease-in-out min-h-screen" style="padding-top:56px"><main class="p-6"><div class="flex items-center justify-between mb-4 h-5"><div class="text-base"><a class="text-sky-blue hover:underline leading-none" href="/dashboard/clusters">Sky Clusters</a></div><div class="flex items-center"><button class="justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 hover:bg-accent h-10 px-4 py-2 text-sky-blue hover:text-sky-blue-bright flex items-center"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-rotate-cw h-4 w-4 mr-1.5"><path d="M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8"></path><path d="M21 3v5h-5"></path></svg><span>Refresh</span></button></div></div><div><div class="rounded-lg border bg-card text-card-foreground shadow-sm"><div class="relative w-full overflow-auto"><table class="w-full caption-bottom text-base"><thead class="[&amp;_tr]:border-b"><tr class="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted"><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">Status</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">Cluster</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">User</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">Resources</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">Region</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0 sortable whitespace-nowrap">Started</th><th class="h-12 px-4 text-left align-middle font-medium text-[hsl(var(--text-strong))] [&amp;:has([role=checkbox])]:pr-0">Actions</th></tr></thead><tbody class="[&amp;_tr:last-child]:border-0"><tr class="border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted"><td class="p-4 align-middle [&amp;:has([role=checkbox])]:pr-0 text-center py-6 text-gray-500" colSpan="8">No active clusters</td></tr></tbody></table></div></div></div></main></div></div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/clusters","query":{},"buildId":"WO8lTFPfj-lO3_gDGEiN8","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/index-f9f039532ca8cbc4.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"MqmRhu1oPMgLy6v25hibm","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/index-f9f039532ca8cbc4.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_ssgManifest.js" defer=""></script></head><body><div id="__next"></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/","query":{},"buildId":"WO8lTFPfj-lO3_gDGEiN8","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
@@ -1 +1 @@
1
- <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/678-206dddca808e6d16.js" defer=""></script><script src="/dashboard/_next/static/chunks/979-7bf73a4c7cea0f5c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-1c519e1afc523dc9.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/MqmRhu1oPMgLy6v25hibm/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div>Loading...</div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"MqmRhu1oPMgLy6v25hibm","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>
1
+ <!DOCTYPE html><html><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width"/><meta name="next-head-count" content="2"/><link rel="preload" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" as="style"/><link rel="stylesheet" href="/dashboard/_next/static/css/c6933bbb2ce7f4dd.css" data-n-g=""/><noscript data-n-css=""></noscript><script defer="" nomodule="" src="/dashboard/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js"></script><script src="/dashboard/_next/static/chunks/webpack-830f59b8404e96b8.js" defer=""></script><script src="/dashboard/_next/static/chunks/framework-87d061ee6ed71b28.js" defer=""></script><script src="/dashboard/_next/static/chunks/main-e0e2335212e72357.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/_app-e6b013bc3f77ad60.js" defer=""></script><script src="/dashboard/_next/static/chunks/678-206dddca808e6d16.js" defer=""></script><script src="/dashboard/_next/static/chunks/979-7bf73a4c7cea0f5c.js" defer=""></script><script src="/dashboard/_next/static/chunks/pages/jobs/%5Bjob%5D-1c519e1afc523dc9.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_buildManifest.js" defer=""></script><script src="/dashboard/_next/static/WO8lTFPfj-lO3_gDGEiN8/_ssgManifest.js" defer=""></script></head><body><div id="__next"><div>Loading...</div></div><script id="__NEXT_DATA__" type="application/json">{"props":{"pageProps":{}},"page":"/jobs/[job]","query":{},"buildId":"WO8lTFPfj-lO3_gDGEiN8","assetPrefix":"/dashboard","nextExport":true,"autoExport":true,"isFallback":false,"scriptLoader":[]}</script></body></html>