wafer-cli 0.2.14__py3-none-any.whl → 0.2.30__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.
wafer/GUIDE.md CHANGED
@@ -7,7 +7,7 @@ GPU development primitives for LLM agents.
7
7
  Run code on cloud GPUs instantly with workspaces:
8
8
 
9
9
  ```bash
10
- wafer login # One-time auth
10
+ wafer auth login # One-time auth
11
11
  wafer workspaces create dev --gpu B200 # Create workspace (NVIDIA B200)
12
12
  wafer workspaces exec dev -- python -c "import torch; print(torch.cuda.get_device_name(0))"
13
13
  wafer workspaces sync dev ./my-project # Sync files
@@ -0,0 +1,42 @@
1
+ """Shared agent defaults for kernel optimization tasks.
2
+
3
+ Single source of truth for bash allowlists and enabled tools used by both:
4
+ - CLI templates (apps/wafer-cli/wafer/templates/optimize_kernelbench.py)
5
+ - Eval configs (research/evals/optimize_kernelbench_eval/.../base_config.py)
6
+
7
+ Import from here instead of defining your own copy.
8
+ """
9
+
10
+ from __future__ import annotations
11
+
12
+ # Tools available to the agent (coding environment tools)
13
+ ENABLED_TOOLS: list[str] = ["read", "write", "edit", "glob", "grep", "bash"]
14
+
15
+ # Bash commands allowed for kernel optimization agents.
16
+ # Uses prefix matching — "wafer evaluate" also allows "wafer evaluate kernelbench".
17
+ KERNELBENCH_BASH_ALLOWLIST: list[str] = [
18
+ # Kernel evaluation
19
+ "wafer evaluate",
20
+ # Profiling — AMD
21
+ "wafer amd rocprof-compute",
22
+ "wafer amd rocprof-sdk",
23
+ "wafer amd rocprof-systems",
24
+ # Profiling — NVIDIA
25
+ "wafer nvidia ncu",
26
+ "wafer nvidia nsys",
27
+ # Analysis
28
+ "wafer compiler-analyze",
29
+ # Sub-agents
30
+ "wafer agent -t ask-docs",
31
+ # General utilities
32
+ "python",
33
+ "python3",
34
+ "timeout",
35
+ "ls",
36
+ "cat",
37
+ "head",
38
+ "tail",
39
+ "wc",
40
+ "pwd",
41
+ "which",
42
+ ]
wafer/auth.py CHANGED
@@ -191,6 +191,10 @@ def get_valid_token() -> str | None:
191
191
  if e.response.status_code != 401:
192
192
  # Not an auth error, re-raise
193
193
  raise
194
+ except httpx.RequestError:
195
+ # Network error (timeout, connection refused, DNS failure, etc.)
196
+ # Cannot verify token - return None to trigger re-login prompt
197
+ return None
194
198
 
195
199
  # Token expired, try refresh
196
200
  if not creds.refresh_token:
@@ -203,6 +207,9 @@ def get_valid_token() -> str | None:
203
207
  except httpx.HTTPStatusError:
204
208
  # Refresh failed, need to re-login
205
209
  return None
210
+ except httpx.RequestError:
211
+ # Network error during refresh - return None to trigger re-login prompt
212
+ return None
206
213
 
207
214
 
208
215
  def _find_free_port() -> int:
wafer/billing.py CHANGED
@@ -1,6 +1,6 @@
1
1
  """Billing CLI - Manage credits and subscription.
2
2
 
3
- This module provides the implementation for the `wafer billing` subcommand.
3
+ This module provides the implementation for the `wafer config billing` subcommand.
4
4
  """
5
5
 
6
6
  import json
@@ -126,7 +126,7 @@ def format_usage_text(usage: dict) -> str:
126
126
  lines.extend([
127
127
  "",
128
128
  "Upgrade to Pro for hardware counters and credit topups:",
129
- " wafer billing portal",
129
+ " wafer config billing portal",
130
130
  ])
131
131
 
132
132
  return "\n".join(lines)
@@ -153,7 +153,7 @@ def get_usage(json_output: bool = False) -> str:
153
153
  usage = response.json()
154
154
  except httpx.HTTPStatusError as e:
155
155
  if e.response.status_code == 401:
156
- raise RuntimeError("Not authenticated. Run: wafer login") from e
156
+ raise RuntimeError("Not authenticated. Run: wafer auth login") from e
157
157
  raise RuntimeError(f"API error: {e.response.status_code} - {e.response.text}") from e
158
158
  except httpx.RequestError as e:
159
159
  raise RuntimeError(f"Could not reach API: {e}") from e
@@ -188,7 +188,7 @@ def create_topup(amount_cents: int) -> dict:
188
188
  return response.json()
189
189
  except httpx.HTTPStatusError as e:
190
190
  if e.response.status_code == 401:
191
- raise RuntimeError("Not authenticated. Run: wafer login") from e
191
+ raise RuntimeError("Not authenticated. Run: wafer auth login") from e
192
192
  if e.response.status_code == 400:
193
193
  # Invalid amount
194
194
  try:
@@ -200,7 +200,7 @@ def create_topup(amount_cents: int) -> dict:
200
200
  # Start tier or other restriction
201
201
  raise RuntimeError(
202
202
  "Topup not available for your subscription tier.\n"
203
- "Upgrade your subscription first: wafer billing portal"
203
+ "Upgrade your subscription first: wafer config billing portal"
204
204
  ) from e
205
205
  if e.response.status_code == 503:
206
206
  raise RuntimeError("Billing service temporarily unavailable. Please try again later.") from e
@@ -227,7 +227,7 @@ def get_portal_url() -> dict:
227
227
  return response.json()
228
228
  except httpx.HTTPStatusError as e:
229
229
  if e.response.status_code == 401:
230
- raise RuntimeError("Not authenticated. Run: wafer login") from e
230
+ raise RuntimeError("Not authenticated. Run: wafer auth login") from e
231
231
  raise RuntimeError(f"API error: {e.response.status_code} - {e.response.text}") from e
232
232
  except httpx.RequestError as e:
233
233
  raise RuntimeError(f"Could not reach API: {e}") from e