Upload 14 files
Browse files- src/bucket.py +23 -15
- src/version.py +2 -2
- src/view_models.py +7 -7
- src/worker_payload.py +4 -4
src/bucket.py
CHANGED
|
@@ -964,18 +964,18 @@ def _classify_build_status_text(text: str) -> str:
|
|
| 964 |
return "technical_blocker_boot_only"
|
| 965 |
if any(x in text for x in ("technical_blocker", "technical blocker", "blocked")):
|
| 966 |
return "technical_blocker"
|
| 967 |
-
if any(x in text for x in ("
|
| 968 |
-
return "full_inference_success"
|
| 969 |
-
if any(x in text for x in ("partial_validation", "full_inference_candidate_health_passed", "health_only", "not_verified", "completed_with_warnings")):
|
| 970 |
-
return "partial_validation"
|
| 971 |
-
if any(x in text for x in ("failed", "failure", "error", "timeout")):
|
| 972 |
return "failed"
|
| 973 |
-
if any(x in text for x in ("success", "succeed", "passed", "completed")):
|
| 974 |
-
return "full_inference_success"
|
| 975 |
if "stale" in text:
|
| 976 |
return "stale"
|
| 977 |
if any(x in text for x in ("cancelled", "canceled", "stopped")):
|
| 978 |
return "stopped"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 979 |
if any(x in text for x in ("running", "queued", "pending", "building", "waiting", "started")):
|
| 980 |
return "running"
|
| 981 |
return ""
|
|
@@ -1066,17 +1066,25 @@ def _canonical_build_status_from_sources(
|
|
| 1066 |
if hard_status and hard_status not in {"running", "full_inference_success", "partial_validation"}:
|
| 1067 |
return hard_status
|
| 1068 |
|
| 1069 |
-
#
|
| 1070 |
-
#
|
| 1071 |
-
|
| 1072 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1073 |
if terminal_status and terminal_status not in {"running", "full_inference_success", "partial_validation"}:
|
| 1074 |
return terminal_status
|
| 1075 |
|
| 1076 |
-
|
| 1077 |
-
|
| 1078 |
-
|
| 1079 |
-
# Active Run panel on first page load.
|
| 1080 |
if _has_persisted_generation_success(summary_file, smoke, gate, manual_validation, state):
|
| 1081 |
return "full_inference_success"
|
| 1082 |
|
|
|
|
| 964 |
return "technical_blocker_boot_only"
|
| 965 |
if any(x in text for x in ("technical_blocker", "technical blocker", "blocked")):
|
| 966 |
return "technical_blocker"
|
| 967 |
+
if any(x in text for x in ("failed", "failure", "error", "timeout", "exception")):
|
|
|
|
|
|
|
|
|
|
|
|
|
| 968 |
return "failed"
|
|
|
|
|
|
|
| 969 |
if "stale" in text:
|
| 970 |
return "stale"
|
| 971 |
if any(x in text for x in ("cancelled", "canceled", "stopped")):
|
| 972 |
return "stopped"
|
| 973 |
+
if any(x in text for x in ("partial_validation", "full_inference_candidate_health_passed", "health_only", "not_verified", "completed_with_warnings")):
|
| 974 |
+
return "partial_validation"
|
| 975 |
+
if "full_inference_success" in text:
|
| 976 |
+
return "full_inference_success"
|
| 977 |
+
if any(x in text for x in ("success", "succeed", "passed", "completed")):
|
| 978 |
+
return "full_inference_success"
|
| 979 |
if any(x in text for x in ("running", "queued", "pending", "building", "waiting", "started")):
|
| 980 |
return "running"
|
| 981 |
return ""
|
|
|
|
| 1066 |
if hard_status and hard_status not in {"running", "full_inference_success", "partial_validation"}:
|
| 1067 |
return hard_status
|
| 1068 |
|
| 1069 |
+
# Explicit final summary success is authoritative. It is the one case where
|
| 1070 |
+
# a stale health-only state should not keep the Explorer badge partial.
|
| 1071 |
+
if summary_status == "full_inference_success":
|
| 1072 |
+
return "full_inference_success"
|
| 1073 |
+
|
| 1074 |
+
# Partial summary/state values are protected for Run Explorer badges: nested
|
| 1075 |
+
# smoke/gate success or failure can provide detail, but must not silently
|
| 1076 |
+
# promote/downgrade the build outcome card.
|
| 1077 |
+
if summary_status == "partial_validation" or state_status_for_guard == "partial_validation":
|
| 1078 |
+
return "partial_validation"
|
| 1079 |
+
|
| 1080 |
+
# Manual/blocker/failure evidence is stronger than a smoke artifact once the
|
| 1081 |
+
# parent summary/state did not already establish a protected partial outcome.
|
| 1082 |
if terminal_status and terminal_status not in {"running", "full_inference_success", "partial_validation"}:
|
| 1083 |
return terminal_status
|
| 1084 |
|
| 1085 |
+
if terminal_status == "partial_validation":
|
| 1086 |
+
return "partial_validation"
|
| 1087 |
+
|
|
|
|
| 1088 |
if _has_persisted_generation_success(summary_file, smoke, gate, manual_validation, state):
|
| 1089 |
return "full_inference_success"
|
| 1090 |
|
src/version.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
-
ASF_APP_VERSION = "
|
| 4 |
-
ASF_RELEASE_NAME = "Agentic Space Factory
|
| 5 |
|
| 6 |
|
| 7 |
def resolve_app_version(value: str | None = None) -> str:
|
|
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
+
ASF_APP_VERSION = "v196"
|
| 4 |
+
ASF_RELEASE_NAME = "Agentic Space Factory v196"
|
| 5 |
|
| 6 |
|
| 7 |
def resolve_app_version(value: str | None = None) -> str:
|
src/view_models.py
CHANGED
|
@@ -37,7 +37,7 @@ MANUAL_RAW_STATUSES = {
|
|
| 37 |
}
|
| 38 |
FAILED_RAW_STATUSES = {"failed", "failure", "error", "repair_failed"}
|
| 39 |
CANCELLED_RAW_STATUSES = {"cancelled", "canceled"}
|
| 40 |
-
BLOCKED_RAW_STATUSES = {"technical_blocker", "technical_blocker_boot_only", "blocked"
|
| 41 |
RUNNING_RAW_STATUSES = {"started", "running", "waiting", "queued", "pending", "scheduled"}
|
| 42 |
AUTH_RAW_STATUSES = {"auth_refresh_required", "oauth_expired", "auth_expired", "repair_validation_inconclusive_auth", "inconclusive_auth_expired"}
|
| 43 |
|
|
@@ -189,15 +189,15 @@ def normalize_run_status(
|
|
| 189 |
elif blocker:
|
| 190 |
global_status = "blocked"
|
| 191 |
verdict = "technical_blocker_boot_only" if "technical_blocker_boot_only" in statuses else "technical_blocker"
|
| 192 |
-
elif statuses.intersection(SUCCESS_RAW_STATUSES):
|
| 193 |
-
global_status = "succeeded"
|
| 194 |
-
verdict = "passed"
|
| 195 |
-
elif statuses.intersection(PARTIAL_RAW_STATUSES):
|
| 196 |
-
global_status = "partial"
|
| 197 |
-
verdict = "partial_validation"
|
| 198 |
elif statuses.intersection(FAILED_RAW_STATUSES):
|
| 199 |
global_status = "failed"
|
| 200 |
verdict = "failed"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
elif statuses.intersection(RUNNING_RAW_STATUSES) or bundle.get("events") or launch:
|
| 202 |
global_status = "running"
|
| 203 |
verdict = "pending"
|
|
|
|
| 37 |
}
|
| 38 |
FAILED_RAW_STATUSES = {"failed", "failure", "error", "repair_failed"}
|
| 39 |
CANCELLED_RAW_STATUSES = {"cancelled", "canceled"}
|
| 40 |
+
BLOCKED_RAW_STATUSES = {"technical_blocker", "technical_blocker_boot_only", "blocked"}
|
| 41 |
RUNNING_RAW_STATUSES = {"started", "running", "waiting", "queued", "pending", "scheduled"}
|
| 42 |
AUTH_RAW_STATUSES = {"auth_refresh_required", "oauth_expired", "auth_expired", "repair_validation_inconclusive_auth", "inconclusive_auth_expired"}
|
| 43 |
|
|
|
|
| 189 |
elif blocker:
|
| 190 |
global_status = "blocked"
|
| 191 |
verdict = "technical_blocker_boot_only" if "technical_blocker_boot_only" in statuses else "technical_blocker"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
elif statuses.intersection(FAILED_RAW_STATUSES):
|
| 193 |
global_status = "failed"
|
| 194 |
verdict = "failed"
|
| 195 |
+
elif statuses.intersection(PARTIAL_RAW_STATUSES):
|
| 196 |
+
global_status = "partial"
|
| 197 |
+
verdict = "partial_validation"
|
| 198 |
+
elif statuses.intersection(SUCCESS_RAW_STATUSES):
|
| 199 |
+
global_status = "succeeded"
|
| 200 |
+
verdict = "passed"
|
| 201 |
elif statuses.intersection(RUNNING_RAW_STATUSES) or bundle.get("events") or launch:
|
| 202 |
global_status = "running"
|
| 203 |
verdict = "pending"
|
src/worker_payload.py
CHANGED
|
@@ -7000,8 +7000,8 @@ def smoke_generate(target_space_id: str, token: str, run_dir: Path, events_path:
|
|
| 7000 |
# write_json(run_dir / "tests" / "payload_source.json", payload_source_record)
|
| 7001 |
# write_json(run_dir / "tests" / "replay_source.json", replay_source)
|
| 7002 |
# write_json(run_dir / "tests" / "validation_preflight.json", validation_preflight)
|
| 7003 |
-
app_version = "
|
| 7004 |
-
engine_version = "
|
| 7005 |
parent_build_run_id = os.environ.get("PARENT_BUILD_RUN_ID", "").strip()
|
| 7006 |
validation_mode = os.environ.get("VALIDATION_MODE") or os.environ.get("SPACE_TEST_POLICY_MODE") or "linked"
|
| 7007 |
requested_api_name = (os.environ.get("API_NAME") or "").strip()
|
|
@@ -7422,7 +7422,7 @@ Target Space: [`{target_space_id}`](https://huggingface.co/spaces/{target_space_
|
|
| 7422 |
except Exception as eval_exc:
|
| 7423 |
append_event(events_path, "anonymous_eval", "warning", "Could not publish anonymized validation evaluation record", {"error": str(eval_exc)[:1000]})
|
| 7424 |
# Rewrite the terminal summary at the very end of the success path.
|
| 7425 |
-
#
|
| 7426 |
# final lightweight summary is not the last writer visible in the
|
| 7427 |
# bucket sync. Keep manual audits and list views terminal-consistent.
|
| 7428 |
write_final_summary(run_dir, final_state, {}, smoke, status="full_inference_success", message=final_state.get("message"))
|
|
@@ -7463,7 +7463,7 @@ Target Space: [`{target_space_id}`](https://huggingface.co/spaces/{target_space_
|
|
| 7463 |
append_event(events_path, "anonymous_eval", "success", "Published anonymized failed validation evaluation record locally for backend archive publishing", {"enabled": True, "publish_mode": "backend", "archive_publish_confirmed": False})
|
| 7464 |
except Exception as eval_exc:
|
| 7465 |
append_event(events_path, "anonymous_eval", "warning", "Could not publish anonymized failed validation evaluation record", {"error": str(eval_exc)[:1000]})
|
| 7466 |
-
#
|
| 7467 |
# for linked validations, so a failed validation cannot remain listed
|
| 7468 |
# as running after the worker has already terminalized state.json.
|
| 7469 |
write_final_summary(run_dir, failure_state, {}, {"status": terminal_status, "failure_type": details.get("failure_type", "linked_validation_failed") if isinstance(details, dict) else "linked_validation_failed"}, status=terminal_status, message=str(failure_state.get("message") or details.get("error", "Existing Space validation failed")) if isinstance(details, dict) else "Existing Space validation failed")
|
|
|
|
| 7000 |
# write_json(run_dir / "tests" / "payload_source.json", payload_source_record)
|
| 7001 |
# write_json(run_dir / "tests" / "replay_source.json", replay_source)
|
| 7002 |
# write_json(run_dir / "tests" / "validation_preflight.json", validation_preflight)
|
| 7003 |
+
app_version = "v196"
|
| 7004 |
+
engine_version = "unified_gradio_validation_harness_v196"
|
| 7005 |
parent_build_run_id = os.environ.get("PARENT_BUILD_RUN_ID", "").strip()
|
| 7006 |
validation_mode = os.environ.get("VALIDATION_MODE") or os.environ.get("SPACE_TEST_POLICY_MODE") or "linked"
|
| 7007 |
requested_api_name = (os.environ.get("API_NAME") or "").strip()
|
|
|
|
| 7422 |
except Exception as eval_exc:
|
| 7423 |
append_event(events_path, "anonymous_eval", "warning", "Could not publish anonymized validation evaluation record", {"error": str(eval_exc)[:1000]})
|
| 7424 |
# Rewrite the terminal summary at the very end of the success path.
|
| 7425 |
+
# v194: launch metadata can leave summary.json as running if the
|
| 7426 |
# final lightweight summary is not the last writer visible in the
|
| 7427 |
# bucket sync. Keep manual audits and list views terminal-consistent.
|
| 7428 |
write_final_summary(run_dir, final_state, {}, smoke, status="full_inference_success", message=final_state.get("message"))
|
|
|
|
| 7463 |
append_event(events_path, "anonymous_eval", "success", "Published anonymized failed validation evaluation record locally for backend archive publishing", {"enabled": True, "publish_mode": "backend", "archive_publish_confirmed": False})
|
| 7464 |
except Exception as eval_exc:
|
| 7465 |
append_event(events_path, "anonymous_eval", "warning", "Could not publish anonymized failed validation evaluation record", {"error": str(eval_exc)[:1000]})
|
| 7466 |
+
# v194: also rewrite failure summary as the final visible file update
|
| 7467 |
# for linked validations, so a failed validation cannot remain listed
|
| 7468 |
# as running after the worker has already terminalized state.json.
|
| 7469 |
write_final_summary(run_dir, failure_state, {}, {"status": terminal_status, "failure_type": details.get("failure_type", "linked_validation_failed") if isinstance(details, dict) else "linked_validation_failed"}, status=terminal_status, message=str(failure_state.get("message") or details.get("error", "Existing Space validation failed")) if isinstance(details, dict) else "Existing Space validation failed")
|