konduktor-nightly 0.1.0.dev20250810104857__tar.gz → 0.1.0.dev20250811105223__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.

Potentially problematic release.


This version of konduktor-nightly might be problematic. Click here for more details.

Files changed (103) hide show
  1. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/PKG-INFO +1 -1
  2. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/__init__.py +2 -2
  3. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/backends/jobset_utils.py +6 -2
  4. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/cli.py +22 -9
  5. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/logging.py +6 -4
  6. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/ux_utils.py +25 -11
  7. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/pyproject.toml +1 -1
  8. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/LICENSE +0 -0
  9. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/README.md +0 -0
  10. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/adaptors/__init__.py +0 -0
  11. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/adaptors/aws.py +0 -0
  12. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/adaptors/common.py +0 -0
  13. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/adaptors/gcp.py +0 -0
  14. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/authentication.py +0 -0
  15. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/backends/__init__.py +0 -0
  16. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/backends/backend.py +0 -0
  17. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/backends/constants.py +0 -0
  18. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/backends/deployment.py +0 -0
  19. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/backends/deployment_utils.py +0 -0
  20. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/backends/jobset.py +0 -0
  21. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/backends/pod_utils.py +0 -0
  22. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/check.py +0 -0
  23. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/config.py +0 -0
  24. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/constants.py +0 -0
  25. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/controller/__init__.py +0 -0
  26. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/controller/constants.py +0 -0
  27. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/controller/launch.py +0 -0
  28. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/controller/node.py +0 -0
  29. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/controller/parse.py +0 -0
  30. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/README.md +0 -0
  31. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/backend/main.py +0 -0
  32. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/backend/sockets.py +0 -0
  33. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/.eslintrc.json +0 -0
  34. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/.gitignore +0 -0
  35. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/api/jobs/route.js +0 -0
  36. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/api/namespaces/route.js +0 -0
  37. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/Grafana.jsx +0 -0
  38. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/JobsData.jsx +0 -0
  39. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/LogsData.jsx +0 -0
  40. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/NavMenu.jsx +0 -0
  41. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/NavTabs.jsx +0 -0
  42. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/NavTabs2.jsx +0 -0
  43. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/SelectBtn.jsx +0 -0
  44. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/lib/utils.js +0 -0
  45. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/ui/chip-select.jsx +0 -0
  46. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/ui/input.jsx +0 -0
  47. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/ui/navigation-menu.jsx +0 -0
  48. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/components/ui/select.jsx +0 -0
  49. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/favicon.ico +0 -0
  50. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/globals.css +0 -0
  51. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/jobs/page.js +0 -0
  52. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/layout.js +0 -0
  53. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/logs/page.js +0 -0
  54. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/app/page.js +0 -0
  55. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/jsconfig.json +0 -0
  56. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/next.config.mjs +0 -0
  57. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/package-lock.json +0 -0
  58. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/package.json +0 -0
  59. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/postcss.config.mjs +0 -0
  60. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/server.js +0 -0
  61. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/dashboard/frontend/tailwind.config.js +0 -0
  62. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/__init__.py +0 -0
  63. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/aws/__init__.py +0 -0
  64. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/aws/s3.py +0 -0
  65. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/constants.py +0 -0
  66. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/data_utils.py +0 -0
  67. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/gcp/__init__.py +0 -0
  68. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/gcp/constants.py +0 -0
  69. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/gcp/gcs.py +0 -0
  70. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/gcp/utils.py +0 -0
  71. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/registry.py +0 -0
  72. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/storage.py +0 -0
  73. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/data/storage_utils.py +0 -0
  74. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/execution.py +0 -0
  75. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/kube_client.py +0 -0
  76. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/manifests/controller_deployment.yaml +0 -0
  77. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/manifests/dashboard_deployment.yaml +0 -0
  78. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/manifests/dmesg_daemonset.yaml +0 -0
  79. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/manifests/pod_cleanup_controller.yaml +0 -0
  80. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/resource.py +0 -0
  81. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/serving.py +0 -0
  82. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/task.py +0 -0
  83. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/templates/deployment.yaml.j2 +0 -0
  84. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/templates/jobset.yaml.j2 +0 -0
  85. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/templates/pod.yaml.j2 +0 -0
  86. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/usage/__init__.py +0 -0
  87. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/usage/constants.py +0 -0
  88. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/__init__.py +0 -0
  89. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/accelerator_registry.py +0 -0
  90. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/annotations.py +0 -0
  91. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/base64_utils.py +0 -0
  92. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/common_utils.py +0 -0
  93. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/constants.py +0 -0
  94. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/env_options.py +0 -0
  95. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/exceptions.py +0 -0
  96. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/kubernetes_enums.py +0 -0
  97. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/kubernetes_utils.py +0 -0
  98. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/log_utils.py +0 -0
  99. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/loki_utils.py +0 -0
  100. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/rich_utils.py +0 -0
  101. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/schemas.py +0 -0
  102. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/subprocess_utils.py +0 -0
  103. {konduktor_nightly-0.1.0.dev20250810104857 → konduktor_nightly-0.1.0.dev20250811105223}/konduktor/utils/validator.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: konduktor-nightly
3
- Version: 0.1.0.dev20250810104857
3
+ Version: 0.1.0.dev20250811105223
4
4
  Summary: GPU Cluster Health Management
5
5
  Author: Andrew Aikawa
6
6
  Author-email: asai@berkeley.edu
@@ -11,7 +11,7 @@ from konduktor.task import Task
11
11
  __all__ = ['launch', 'Resources', 'Task', 'Serving']
12
12
 
13
13
  # Replaced with the current commit when building the wheels.
14
- _KONDUKTOR_COMMIT_SHA = '0f0b36c3a67aa7c60d6cb33240631b7c8ccaed03'
14
+ _KONDUKTOR_COMMIT_SHA = '92fe69bd3f29e7b191de663c598dfcf10738f87a'
15
15
  os.makedirs(os.path.expanduser('~/.konduktor'), exist_ok=True)
16
16
 
17
17
 
@@ -45,5 +45,5 @@ def _get_git_commit():
45
45
 
46
46
 
47
47
  __commit__ = _get_git_commit()
48
- __version__ = '1.0.0.dev0.1.0.dev20250810104857'
48
+ __version__ = '1.0.0.dev0.1.0.dev20250811105223'
49
49
  __root_dir__ = os.path.dirname(os.path.abspath(__file__))
@@ -232,8 +232,12 @@ def stop_jobset(namespace: str, job_name: str) -> Optional[Dict[str, Any]]:
232
232
  'spec': {'suspend': True},
233
233
  'metadata': {
234
234
  'annotations': {
235
- backend_constants.STOP_USERID_LABEL: common_utils.user_and_hostname_hash(),
236
- backend_constants.STOP_USERNAME_LABEL: common_utils.get_cleaned_username(),
235
+ backend_constants.STOP_USERID_LABEL: (
236
+ common_utils.user_and_hostname_hash()
237
+ ),
238
+ backend_constants.STOP_USERNAME_LABEL: (
239
+ common_utils.get_cleaned_username()
240
+ ),
237
241
  }
238
242
  },
239
243
  }
@@ -855,16 +855,23 @@ def launch(
855
855
  'Serving information detected. Use '
856
856
  '`konduktor serve launch` instead for serving.'
857
857
  )
858
+ try:
859
+ _launch_with_confirm(
860
+ task,
861
+ dryrun=dryrun,
862
+ detach_run=detach_run,
863
+ no_confirm=yes,
864
+ serving=bool(task.serving),
865
+ )
866
+ except KeyboardInterrupt:
867
+ click.secho(
868
+ f'Detaching... manage your job {task.name} with the following commands:',
869
+ fg='yellow',
870
+ bold=True,
871
+ )
858
872
 
859
- job_name = _launch_with_confirm(
860
- task,
861
- dryrun=dryrun,
862
- detach_run=detach_run,
863
- no_confirm=yes,
864
- serving=bool(task.serving),
865
- )
866
873
  click.secho(
867
- ux_utils.command_hint_messages(ux_utils.CommandHintType.JOB, job_name),
874
+ ux_utils.command_hint_messages(ux_utils.CommandHintType.JOB, task.name),
868
875
  fg='green',
869
876
  bold=True,
870
877
  )
@@ -1139,6 +1146,12 @@ def stop(
1139
1146
  for job in track(jobs, description='Suspending job(s)...'):
1140
1147
  jobset_utils.stop_jobset(namespace, job)
1141
1148
 
1149
+ click.secho(
1150
+ ux_utils.command_hint_messages(ux_utils.CommandHintType.JOB_STOP, jobs),
1151
+ fg='green',
1152
+ bold=True,
1153
+ )
1154
+
1142
1155
 
1143
1156
  @cli.command(cls=_DocumentedCodeCommand)
1144
1157
  @click.argument(
@@ -1836,7 +1849,7 @@ def main():
1836
1849
  return cli(standalone_mode=False)
1837
1850
  except click.exceptions.Abort:
1838
1851
  click.secho('Detaching...', fg='yellow', bold=True)
1839
- return
1852
+ return None
1840
1853
 
1841
1854
 
1842
1855
  if __name__ == '__main__':
@@ -75,12 +75,14 @@ def get_logger(name: str):
75
75
  fh.setFormatter(FORMATTER)
76
76
  logger.addHandler(fh)
77
77
 
78
- # --- Console logging: DEBUG level only if KONDUKTOR_DEBUG=1 ---
78
+ # --- Console logging: INFO level by default, DEBUG if KONDUKTOR_DEBUG=1 ---
79
+ ch = logging.StreamHandler()
79
80
  if os.environ.get('KONDUKTOR_DEBUG') == '1':
80
- ch = logging.StreamHandler()
81
81
  ch.setLevel(logging.DEBUG)
82
- ch.setFormatter(FORMATTER)
83
- logger.addHandler(ch)
82
+ else:
83
+ ch.setLevel(logging.INFO)
84
+ ch.setFormatter(FORMATTER)
85
+ logger.addHandler(ch)
84
86
 
85
87
  logger.propagate = False
86
88
  return logger
@@ -6,7 +6,7 @@ import os
6
6
  import sys
7
7
  import traceback
8
8
  import typing
9
- from typing import Callable, Optional, Union
9
+ from typing import Callable, List, Optional, Union
10
10
 
11
11
  import colorama
12
12
  import rich.console as rich_console
@@ -196,27 +196,41 @@ def spinner_message(
196
196
 
197
197
  class CommandHintType(enum.Enum):
198
198
  JOB = 'JOB'
199
+ JOB_STOP = 'JOB_STOP'
199
200
 
200
201
 
201
- def command_hint_messages(hint_type: CommandHintType, job_id: str) -> str:
202
+ def command_hint_messages(
203
+ hint_type: CommandHintType,
204
+ job_id: Union[str, List[str]],
205
+ ) -> str:
202
206
  """Gets the command hint messages for the given job id."""
207
+ hint_str = '\n📋 Useful Commands'
203
208
  if hint_type == CommandHintType.JOB:
204
209
  job_hint_str = (
205
210
  f'\nJob ID: {job_id}'
206
- f'\n{INDENT_SYMBOL}To cancel the job:\t\t'
207
- f'{BOLD}konduktor down {job_id} {RESET_BOLD}'
208
211
  f'\n{INDENT_SYMBOL}To stream job logs:\t\t'
209
212
  f'{BOLD}konduktor logs {job_id} {RESET_BOLD}'
210
213
  f'\n{INDENT_SYMBOL}To list all jobs:\t\t'
211
214
  f'{BOLD}konduktor status{RESET_BOLD}'
215
+ f'\n{INDENT_SYMBOL}To suspend the job:\t\t'
216
+ f'{BOLD}konduktor stop {job_id} {RESET_BOLD}'
217
+ f'\n{INDENT_SYMBOL}{colorama.Fore.RED}To delete the job:\t\t'
218
+ f'{BOLD}konduktor down {job_id} {RESET_BOLD}{colorama.Style.RESET_ALL}'
212
219
  )
213
- hint_str = '\n📋 Useful Commands'
214
220
  hint_str += f'{job_hint_str}'
215
- if config.get_nested(('tailscale', 'secret_name'), None) is not None:
216
- hint_str += (
217
- f'\n{INDENT_SYMBOL}To tailscale ssh:\t\t'
218
- f'{BOLD}ssh root@{job_id}-workers-0-0 {RESET_BOLD}'
219
- )
220
- return hint_str
221
+ elif hint_type == CommandHintType.JOB_STOP:
222
+ assert isinstance(job_id, list), 'job_id must be a list of strings'
223
+ job_ids_str = ' '.join(job_id)
224
+ hint_str += (
225
+ f'\n{INDENT_SYMBOL}To resume the following jobs:\t\t'
226
+ f'{BOLD}konduktor start {job_ids_str} {RESET_BOLD}'
227
+ )
221
228
  else:
222
229
  raise ValueError(f'Invalid hint type: {hint_type}')
230
+
231
+ if config.get_nested(('tailscale', 'secret_name'), None) is not None:
232
+ hint_str += (
233
+ f'\n{INDENT_SYMBOL}To tailscale ssh:\t\t'
234
+ f'{BOLD}ssh root@{job_id}-workers-0-0 {RESET_BOLD}'
235
+ )
236
+ return hint_str
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "konduktor-nightly"
3
- version = "0.1.0.dev20250810104857"
3
+ version = "0.1.0.dev20250811105223"
4
4
  description = "GPU Cluster Health Management"
5
5
  packages = [
6
6
  {include = "konduktor"}