wafer-core 0.1.38__py3-none-any.whl → 0.1.39__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_core/lib/trace_compare/fusion_analyzer.py +2 -0
- wafer_core/rollouts/_logging/__init__.py +5 -1
- wafer_core/rollouts/_logging/logging_config.py +95 -3
- wafer_core/rollouts/_logging/sample_handler.py +66 -0
- wafer_core/rollouts/_pytui/__init__.py +114 -0
- wafer_core/rollouts/_pytui/app.py +809 -0
- wafer_core/rollouts/_pytui/console.py +291 -0
- wafer_core/rollouts/_pytui/renderer.py +210 -0
- wafer_core/rollouts/_pytui/spinner.py +73 -0
- wafer_core/rollouts/_pytui/terminal.py +489 -0
- wafer_core/rollouts/_pytui/text.py +470 -0
- wafer_core/rollouts/_pytui/theme.py +241 -0
- wafer_core/rollouts/evaluation.py +142 -177
- wafer_core/rollouts/progress_app.py +395 -0
- wafer_core/rollouts/tui/DESIGN.md +251 -115
- wafer_core/rollouts/tui/monitor.py +64 -20
- wafer_core/tools/compile/__init__.py +30 -0
- wafer_core/tools/compile/compiler.py +314 -0
- wafer_core/tools/compile/modal_compile.py +359 -0
- wafer_core/tools/compile/tests/__init__.py +1 -0
- wafer_core/tools/compile/tests/test_compiler.py +675 -0
- wafer_core/tools/compile/tests/test_data/utils.cuh +10 -0
- wafer_core/tools/compile/tests/test_data/vector_add.cu +7 -0
- wafer_core/tools/compile/tests/test_data/with_header.cu +9 -0
- wafer_core/tools/compile/tests/test_modal_integration.py +326 -0
- wafer_core/tools/compile/types.py +117 -0
- {wafer_core-0.1.38.dist-info → wafer_core-0.1.39.dist-info}/METADATA +1 -1
- {wafer_core-0.1.38.dist-info → wafer_core-0.1.39.dist-info}/RECORD +29 -12
- wafer_core/rollouts/events.py +0 -240
- wafer_core/rollouts/progress_display.py +0 -476
- wafer_core/utils/event_streaming.py +0 -63
- {wafer_core-0.1.38.dist-info → wafer_core-0.1.39.dist-info}/WHEEL +0 -0
wafer_core/rollouts/events.py
DELETED
|
@@ -1,240 +0,0 @@
|
|
|
1
|
-
"""Unified event emission for TUI consumption.
|
|
2
|
-
|
|
3
|
-
All long-running processes (eval, GEPA, RL training) emit structured events
|
|
4
|
-
to a JSONL file. The TUI tails this file and renders progress.
|
|
5
|
-
|
|
6
|
-
This decouples the process from the UI - the process doesn't know or care
|
|
7
|
-
if anyone is watching. Events are always written for later analysis too.
|
|
8
|
-
|
|
9
|
-
Event types:
|
|
10
|
-
sample_start/end - Evaluation sample lifecycle
|
|
11
|
-
turn - Agent turn within a sample
|
|
12
|
-
modal_progress - GPU eval phases (compiling, checking, benchmarking)
|
|
13
|
-
gepa_iteration - GEPA optimization progress
|
|
14
|
-
rl_step - RL training step metrics
|
|
15
|
-
log - Generic log message (routed to panes by logger name)
|
|
16
|
-
|
|
17
|
-
Usage:
|
|
18
|
-
from rollouts.events import EventEmitter, get_emitter
|
|
19
|
-
|
|
20
|
-
# In evaluate():
|
|
21
|
-
emitter = EventEmitter(output_dir)
|
|
22
|
-
emitter.emit("sample_start", id="001", name="Square_matmul", total=10)
|
|
23
|
-
# ... do work ...
|
|
24
|
-
emitter.emit("sample_end", id="001", score=0.85, time_sec=45.2)
|
|
25
|
-
|
|
26
|
-
# In GEPA:
|
|
27
|
-
emitter = get_emitter() # Gets from context
|
|
28
|
-
emitter.emit("gepa_iteration", iteration=3, evals_used=12, best_score=0.42)
|
|
29
|
-
|
|
30
|
-
Tiger Style: Pure data out, no UI code, explicit file handle.
|
|
31
|
-
"""
|
|
32
|
-
|
|
33
|
-
from __future__ import annotations
|
|
34
|
-
|
|
35
|
-
import contextvars
|
|
36
|
-
import json
|
|
37
|
-
import logging
|
|
38
|
-
from datetime import datetime, timezone
|
|
39
|
-
from pathlib import Path
|
|
40
|
-
from typing import Any, TextIO
|
|
41
|
-
|
|
42
|
-
logger = logging.getLogger(__name__)
|
|
43
|
-
|
|
44
|
-
# Context variable for accessing emitter from anywhere in the call stack
|
|
45
|
-
_emitter_ctx: contextvars.ContextVar[EventEmitter | None] = contextvars.ContextVar(
|
|
46
|
-
"event_emitter", default=None
|
|
47
|
-
)
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
def get_emitter() -> EventEmitter | None:
|
|
51
|
-
"""Get the current EventEmitter from context.
|
|
52
|
-
|
|
53
|
-
Returns None if no emitter is set (events will be silently dropped).
|
|
54
|
-
"""
|
|
55
|
-
return _emitter_ctx.get()
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
def emit_event(event_type: str, **data: Any) -> None:
|
|
59
|
-
"""Emit an event if an emitter is configured.
|
|
60
|
-
|
|
61
|
-
Convenience function that gets emitter from context.
|
|
62
|
-
Safe to call even if no emitter is set (no-op).
|
|
63
|
-
|
|
64
|
-
Args:
|
|
65
|
-
event_type: Event type (sample_start, turn, modal_progress, etc.)
|
|
66
|
-
**data: Event data fields
|
|
67
|
-
"""
|
|
68
|
-
emitter = get_emitter()
|
|
69
|
-
if emitter is not None:
|
|
70
|
-
emitter.emit(event_type, **data)
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
class EventEmitter:
|
|
74
|
-
"""Writes structured events to JSONL file/stream.
|
|
75
|
-
|
|
76
|
-
Thread-safe via flush-after-write. Events include timestamp automatically.
|
|
77
|
-
|
|
78
|
-
Can write to:
|
|
79
|
-
- File (default): {output_dir}/events.jsonl
|
|
80
|
-
- Stdout: For piping to TUI
|
|
81
|
-
- Any TextIO stream
|
|
82
|
-
|
|
83
|
-
Usage:
|
|
84
|
-
# File-based (for local runs)
|
|
85
|
-
with EventEmitter(output_dir=Path("./results")) as emitter:
|
|
86
|
-
emitter.emit("sample_start", id="001", name="test")
|
|
87
|
-
|
|
88
|
-
# Stdout (for piped runs)
|
|
89
|
-
with EventEmitter(stream=sys.stdout) as emitter:
|
|
90
|
-
emitter.emit("sample_start", id="001", name="test")
|
|
91
|
-
|
|
92
|
-
# With context (accessible via get_emitter())
|
|
93
|
-
with EventEmitter(output_dir=path).as_context():
|
|
94
|
-
emit_event("sample_start", id="001") # Works anywhere in call stack
|
|
95
|
-
"""
|
|
96
|
-
|
|
97
|
-
def __init__(
|
|
98
|
-
self,
|
|
99
|
-
output_dir: Path | str | None = None,
|
|
100
|
-
stream: TextIO | None = None,
|
|
101
|
-
events_file: str = "events.jsonl",
|
|
102
|
-
) -> None:
|
|
103
|
-
"""Initialize emitter.
|
|
104
|
-
|
|
105
|
-
Args:
|
|
106
|
-
output_dir: Directory to write events.jsonl (mutually exclusive with stream)
|
|
107
|
-
stream: Stream to write to (e.g., sys.stdout)
|
|
108
|
-
events_file: Filename within output_dir (default: events.jsonl)
|
|
109
|
-
"""
|
|
110
|
-
self._file: TextIO | None = None
|
|
111
|
-
self._owns_file = False
|
|
112
|
-
self._ctx_token: contextvars.Token | None = None
|
|
113
|
-
|
|
114
|
-
if stream is not None:
|
|
115
|
-
self._file = stream
|
|
116
|
-
self._owns_file = False
|
|
117
|
-
elif output_dir is not None:
|
|
118
|
-
output_path = Path(output_dir)
|
|
119
|
-
output_path.mkdir(parents=True, exist_ok=True)
|
|
120
|
-
self._file = open(output_path / events_file, "a")
|
|
121
|
-
self._owns_file = True
|
|
122
|
-
logger.debug(f"EventEmitter writing to {output_path / events_file}")
|
|
123
|
-
else:
|
|
124
|
-
# No output configured - events will be dropped
|
|
125
|
-
logger.debug("EventEmitter created with no output (events will be dropped)")
|
|
126
|
-
|
|
127
|
-
def emit(self, event_type: str, **data: Any) -> None:
|
|
128
|
-
"""Emit a structured event.
|
|
129
|
-
|
|
130
|
-
Args:
|
|
131
|
-
event_type: Event type (sample_start, sample_end, turn, modal_progress, etc.)
|
|
132
|
-
**data: Event data fields
|
|
133
|
-
"""
|
|
134
|
-
if self._file is None:
|
|
135
|
-
return
|
|
136
|
-
|
|
137
|
-
event = {
|
|
138
|
-
"type": event_type,
|
|
139
|
-
"timestamp": datetime.now(timezone.utc).isoformat(),
|
|
140
|
-
**data,
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
try:
|
|
144
|
-
self._file.write(json.dumps(event) + "\n")
|
|
145
|
-
self._file.flush()
|
|
146
|
-
except Exception as e:
|
|
147
|
-
logger.warning(f"Failed to emit event: {e}")
|
|
148
|
-
|
|
149
|
-
def as_context(self) -> EventEmitter:
|
|
150
|
-
"""Set this emitter as the context emitter.
|
|
151
|
-
|
|
152
|
-
Use as context manager:
|
|
153
|
-
with EventEmitter(output_dir=path).as_context():
|
|
154
|
-
emit_event("sample_start", ...) # Uses this emitter
|
|
155
|
-
|
|
156
|
-
Returns self for chaining.
|
|
157
|
-
"""
|
|
158
|
-
self._ctx_token = _emitter_ctx.set(self)
|
|
159
|
-
return self
|
|
160
|
-
|
|
161
|
-
def __enter__(self) -> EventEmitter:
|
|
162
|
-
return self
|
|
163
|
-
|
|
164
|
-
def __exit__(self, exc_type: Any, exc_val: Any, exc_tb: Any) -> None:
|
|
165
|
-
self.close()
|
|
166
|
-
|
|
167
|
-
def close(self) -> None:
|
|
168
|
-
"""Close the emitter and release resources."""
|
|
169
|
-
# Reset context if we set it
|
|
170
|
-
if self._ctx_token is not None:
|
|
171
|
-
_emitter_ctx.reset(self._ctx_token)
|
|
172
|
-
self._ctx_token = None
|
|
173
|
-
|
|
174
|
-
# Close file if we own it
|
|
175
|
-
if self._owns_file and self._file is not None:
|
|
176
|
-
self._file.close()
|
|
177
|
-
self._file = None
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
class LoggingEventEmitter(EventEmitter):
|
|
181
|
-
"""EventEmitter that also logs events via Python logging.
|
|
182
|
-
|
|
183
|
-
Useful for debugging - events appear in both events.jsonl and logs.
|
|
184
|
-
"""
|
|
185
|
-
|
|
186
|
-
def __init__(
|
|
187
|
-
self,
|
|
188
|
-
output_dir: Path | str | None = None,
|
|
189
|
-
stream: TextIO | None = None,
|
|
190
|
-
events_file: str = "events.jsonl",
|
|
191
|
-
log_level: int = logging.DEBUG,
|
|
192
|
-
) -> None:
|
|
193
|
-
super().__init__(output_dir, stream, events_file)
|
|
194
|
-
self._log_level = log_level
|
|
195
|
-
|
|
196
|
-
def emit(self, event_type: str, **data: Any) -> None:
|
|
197
|
-
super().emit(event_type, **data)
|
|
198
|
-
logger.log(self._log_level, f"Event: {event_type} {data}")
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
# ── Event type constants ──────────────────────────────────────────────────────
|
|
202
|
-
# Use these for consistency across codebase
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
class EventTypes:
|
|
206
|
-
"""Standard event type constants."""
|
|
207
|
-
|
|
208
|
-
# Eval lifecycle
|
|
209
|
-
EVAL_START = "eval_start"
|
|
210
|
-
EVAL_END = "eval_end"
|
|
211
|
-
SAMPLE_START = "sample_start"
|
|
212
|
-
SAMPLE_END = "sample_end"
|
|
213
|
-
TURN = "turn"
|
|
214
|
-
|
|
215
|
-
# Tool execution (wide events)
|
|
216
|
-
TOOL_EXECUTION = "tool_execution"
|
|
217
|
-
LLM_CALL = "llm_call"
|
|
218
|
-
ASSISTANT_MESSAGE = "assistant_message"
|
|
219
|
-
|
|
220
|
-
# GPU/target pool management
|
|
221
|
-
GPU_ACQUIRE = "gpu_acquire"
|
|
222
|
-
GPU_RELEASE = "gpu_release"
|
|
223
|
-
|
|
224
|
-
# Modal/GPU progress
|
|
225
|
-
MODAL_PROGRESS = "modal_progress"
|
|
226
|
-
|
|
227
|
-
# GEPA
|
|
228
|
-
GEPA_START = "gepa_start"
|
|
229
|
-
GEPA_ITERATION = "gepa_iteration"
|
|
230
|
-
GEPA_ACCEPTED = "gepa_accepted"
|
|
231
|
-
GEPA_REJECTED = "gepa_rejected"
|
|
232
|
-
GEPA_END = "gepa_end"
|
|
233
|
-
|
|
234
|
-
# RL Training
|
|
235
|
-
RL_STEP = "rl_step"
|
|
236
|
-
RL_CHECKPOINT = "rl_checkpoint"
|
|
237
|
-
|
|
238
|
-
# Generic
|
|
239
|
-
LOG = "log"
|
|
240
|
-
ERROR = "error"
|