fffiloni commited on
Commit
db921ed
Β·
verified Β·
1 Parent(s): c1f7b6c

Upload 6 files

Browse files
Files changed (3) hide show
  1. CHANGELOG.md +19 -4
  2. README.md +15 -4
  3. app.py +22 -1
CHANGELOG.md CHANGED
@@ -1,10 +1,25 @@
 
1
 
 
 
 
 
2
 
3
- ## v121 latency/display cleanup
4
 
5
- - Reduced perceived latency when re-opening already inspected runs by reusing cached progress/detail payloads immediately and avoiding duplicate polling starts.
6
- - Added DOM render signatures for run documents, Agent recovery and Gradio endpoint panels to prevent flicker during polling.
7
- - Preserved heavy hydration in the background for full reports/artifacts while keeping the central panels responsive.
 
 
 
 
 
 
 
 
 
 
 
8
 
9
 
10
  ## v120 β€” Agent recovery UI for blockage protocol
 
1
+ ## v124 β€” Timeline and Run Explorer stabilization
2
 
3
+ - Fixed the compact Overall Progress timeline so dynamically visible repair/failure groups cannot wrap dots onto a second row.
4
+ - Removed smooth timeline auto-scroll that could cause visible flicker during polling.
5
+ - Simplified Run Explorer type/status badges to neutral type labels and short status labels such as Success, Failed, Running and Manual.
6
+ - Added regression checks for timeline single-row behavior and compact Run Explorer labels.
7
 
 
8
 
9
+ ## v123 β€” Critical Job launch + failure timeline fix
10
+
11
+ - Fixed a production-critical HF Job startup failure where the large embedded worker script could make Python fail before startup with `argument list too long`.
12
+ - The worker script is now persisted as `runs/<run_id>/_worker.py` in the mounted run bucket before launch, and the Job receives only `WORKER_SCRIPT_PATH`.
13
+ - Kept a small `WORKER_SCRIPT_B64` fallback only for compatibility/manual launch paths; normal app launches no longer put the worker source in env/argv.
14
+ - Added a failure-log fallback so pre-worker Job failures such as `argument list too long` still create an explicit failed timeline event and red failure point.
15
+
16
+ ## v122 β€” Stable UI rollback after latency cleanup regression
17
+
18
+ - Reverted the risky v121 client-side run-detail cache/polling optimizations after they caused build/run UI instability and flicker in real usage.
19
+ - Restored the proven v120 Active Run / Space Test selection and polling behavior while keeping the v118/v119/v120 Pi recovery core intact.
20
+ - Kept the Agent recovery panel, unified agent traces, compact Run Explorer, and blockage protocol UI from the stable v120 line.
21
+ - Removed the v121 rendering-signature shortcuts and progress-payload cache writes that could leave panels in stale or inconsistent states.
22
+ - This release prioritizes correctness and stable polling over speculative latency optimization.
23
 
24
 
25
  ## v120 β€” Agent recovery UI for blockage protocol
README.md CHANGED
@@ -42,6 +42,10 @@ The product root `/` is a custom Docker/FastAPI dashboard. `/custom` is kept as
42
 
43
  The UI is organized into three main areas:
44
 
 
 
 
 
45
  ### Left column
46
 
47
  - **Run storage** β€” check or create the signed-in user's private Bucket.
@@ -205,9 +209,16 @@ A code repair is allowed only when Pi selects `patch_code` and the Factory accep
205
 
206
  Repair mode is intentionally strict: it must preserve the original model and real-inference contract, avoid fake/static outputs, keep a cheap health endpoint, and report blockers instead of hiding runtime errors.
207
 
208
- ## v121 latency/display cleanup
 
 
 
 
 
209
 
210
- - Reduced perceived latency when re-opening already inspected runs by reusing cached progress/detail payloads immediately and avoiding duplicate polling starts.
211
- - Added DOM render signatures for run documents, Agent recovery and Gradio endpoint panels to prevent flicker during polling.
212
- - Preserved heavy hydration in the background for full reports/artifacts while keeping the central panels responsive.
213
 
 
 
 
 
 
42
 
43
  The UI is organized into three main areas:
44
 
45
+ ## v122 stability note
46
+
47
+ The v122 line intentionally rolls back the experimental v121 client-side caching/polling optimizations after real UI testing exposed flicker and broken build/run behavior. The app keeps the v120 Agent recovery UI and the v118/v119 core blockage protocol, but returns to the proven polling and run-selection model for production stability.
48
+
49
  ### Left column
50
 
51
  - **Run storage** β€” check or create the signed-in user's private Bucket.
 
209
 
210
  Repair mode is intentionally strict: it must preserve the original model and real-inference contract, avoid fake/static outputs, keep a cheap health endpoint, and report blockers instead of hiding runtime errors.
211
 
212
+ ## v123 β€” Critical Job launch + failure timeline fix
213
+
214
+ - Fixed a production-critical HF Job startup failure where the large embedded worker script could make Python fail before startup with `argument list too long`.
215
+ - The worker script is now persisted as `runs/<run_id>/_worker.py` in the mounted run bucket before launch, and the Job receives only `WORKER_SCRIPT_PATH`.
216
+ - Kept a small `WORKER_SCRIPT_B64` fallback only for compatibility/manual launch paths; normal app launches no longer put the worker source in env/argv.
217
+ - Added a failure-log fallback so pre-worker Job failures such as `argument list too long` still create an explicit failed timeline event and red failure point.
218
 
219
+ ## v124 β€” Timeline and Run Explorer stabilization
 
 
220
 
221
+ - Fixed the compact Overall Progress timeline so dynamically visible repair/failure groups cannot wrap dots onto a second row.
222
+ - Removed smooth timeline auto-scroll that could cause visible flicker during polling.
223
+ - Simplified Run Explorer type/status badges to neutral type labels and short status labels such as Success, Failed, Running and Manual.
224
+ - Added regression checks for timeline single-row behavior and compact Run Explorer labels.
app.py CHANGED
@@ -154,12 +154,17 @@ def _events_from_job_logs(log_text: str) -> list[dict[str, Any]]:
154
  HF Job logs may prefix stdout lines with timestamps, may include ANSI
155
  sequences, and may sometimes have text after a JSON object. Use
156
  JSONDecoder.raw_decode from each opening brace instead of json.loads(line)
157
- so event extraction is not fragile.
 
 
158
  """
159
  events: list[dict[str, Any]] = []
160
  decoder = json.JSONDecoder()
 
161
  for raw in (log_text or "").splitlines():
162
  line = ANSI_RE.sub("", raw).strip()
 
 
163
  for match in re.finditer(r"\{", line):
164
  try:
165
  payload, _ = decoder.raw_decode(line[match.start():])
@@ -168,6 +173,22 @@ def _events_from_job_logs(log_text: str) -> list[dict[str, Any]]:
168
  if isinstance(payload, dict) and payload.get("step") and payload.get("status"):
169
  events.append(payload)
170
  break
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
171
  return events
172
 
173
 
 
154
  HF Job logs may prefix stdout lines with timestamps, may include ANSI
155
  sequences, and may sometimes have text after a JSON object. Use
156
  JSONDecoder.raw_decode from each opening brace instead of json.loads(line)
157
+ so event extraction is not fragile. If the Job fails before the worker can
158
+ write bucket events, synthesize one explicit failure event so the timeline
159
+ still shows a red breakpoint instead of appearing empty/broken.
160
  """
161
  events: list[dict[str, Any]] = []
162
  decoder = json.JSONDecoder()
163
+ clean_lines: list[str] = []
164
  for raw in (log_text or "").splitlines():
165
  line = ANSI_RE.sub("", raw).strip()
166
+ if line:
167
+ clean_lines.append(line)
168
  for match in re.finditer(r"\{", line):
169
  try:
170
  payload, _ = decoder.raw_decode(line[match.start():])
 
173
  if isinstance(payload, dict) and payload.get("step") and payload.get("status"):
174
  events.append(payload)
175
  break
176
+ text = "\n".join(clean_lines).lower()
177
+ if not events and text:
178
+ if "argument list too long" in text:
179
+ events.append({
180
+ "step": "failure",
181
+ "status": "failed",
182
+ "message": "HF Job failed before the worker started: Python argv/env was too large.",
183
+ "details": {"source": "job_logs", "error": "argument list too long"},
184
+ })
185
+ elif any(marker in text for marker in ["traceback", "error", "failed", "exception"]):
186
+ events.append({
187
+ "step": "failure",
188
+ "status": "failed",
189
+ "message": clean_lines[-1][:500] if clean_lines else "HF Job failed before worker events were written.",
190
+ "details": {"source": "job_logs"},
191
+ })
192
  return events
193
 
194