Upload 6 files
Browse files- CHANGELOG.md +29 -6
- README.md +19 -15
- app.py +18 -1
- pyproject.toml +1 -1
- requirements.txt +1 -1
CHANGELOG.md
CHANGED
|
@@ -1,10 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
# v171 — delete Space option, ghost-run cleanup, storage polish
|
| 2 |
|
| 3 |
-
- Added an opt-in checkbox in the premium delete modal to
|
| 4 |
-
-
|
| 5 |
-
-
|
| 6 |
-
-
|
| 7 |
-
- Polished the Run Storage card error state with compact, user-readable messages instead of dumping long bucket HTTP errors into the card.
|
| 8 |
- Preserved the v170 real recursive bucket deletion behavior.
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# v174 — Bucket run-prefix mount and robust worker bootstrap writes
|
| 2 |
+
|
| 3 |
+
- Mounted the `runs/` Storage Bucket prefix explicitly into Jobs using `Volume(type="bucket", source=..., path="runs", mount_path="/output/runs")`.
|
| 4 |
+
- Preserved the worker contract: `OUTPUT_ROOT=/output`, `run_dir=/output/runs/<run_id>`, and remote objects under `runs/<run_id>/`.
|
| 5 |
+
- Hardened API-side `_worker.py` persistence with `HfFileSystem.write_text`, `pipe_file`, `open(..., "wb")`, and a final `sync_bucket` fallback.
|
| 6 |
+
- Removed virtual-directory creation for Bucket prefixes and kept deletion/listing/document links aligned with the configurable run prefix.
|
| 7 |
+
- Raised the minimum `huggingface_hub` requirement to `>=1.11.0`.
|
| 8 |
+
|
| 9 |
+
# v173 — Bucket path separation fix
|
| 10 |
+
|
| 11 |
+
- Reverts the v172 API-side `makedirs` workaround for fresh run prefixes.
|
| 12 |
+
- Keeps a strict distinction between remote bucket object URIs (`hf://buckets/<namespace>/<bucket>/runs/<run_id>/...`) and Job mount paths (`/output/runs/<run_id>/...`).
|
| 13 |
+
- Writes API-side bucket objects directly with `HfFileSystem.pipe_file(...)`, with `open(..., "w")` as a compatibility fallback.
|
| 14 |
+
- Adds tests to prevent treating virtual `runs/` prefixes as directories/repositories.
|
| 15 |
+
|
| 16 |
+
# v172 — fresh bucket writes and pre-scan polish
|
| 17 |
+
|
| 18 |
+
- Keeps Hugging Face Space metadata at the very top of `README.md` so the app archive cannot boot with a configuration error.
|
| 19 |
+
- Makes fresh Bucket run-prefix writes more robust by creating parent prefixes before writing `_worker.py`, `launch.json`, `summary.json`, `state.json`, and other API-authored artifacts.
|
| 20 |
+
- Restyles the Model pre-scan card into a calmer premium status panel with compact metadata chips and less oversized success treatment.
|
| 21 |
+
|
| 22 |
# v171 — delete Space option, ghost-run cleanup, storage polish
|
| 23 |
|
| 24 |
+
- Added an opt-in checkbox in the premium delete modal to delete the associated generated Space for build runs.
|
| 25 |
+
- Kept validation runs protected from accidental associated Space deletion.
|
| 26 |
+
- Made ghost/unknown run prefixes deletable from Run Explorer.
|
| 27 |
+
- Compacted the Run Storage setup error card.
|
|
|
|
| 28 |
- Preserved the v170 real recursive bucket deletion behavior.
|
| 29 |
|
| 30 |
+
# v120 — Agent recovery UI
|
| 31 |
+
|
| 32 |
+
- Added the Agent recovery section to summarize Pi recovery decisions, blockers, evidence, and repair/revalidation status.
|
| 33 |
+
- Kept detailed source files in Run traces instead of duplicating raw recovery logs in the summary card.
|
README.md
CHANGED
|
@@ -13,6 +13,25 @@ hf_oauth_scopes:
|
|
| 13 |
- read-billing
|
| 14 |
---
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
|
| 17 |
## v170 — Real bucket recursive run deletion
|
| 18 |
|
|
@@ -27,21 +46,6 @@ hf_oauth_scopes:
|
|
| 27 |
- **v165** fixes fresh-install recovery failures, README metadata preservation, timeline failure anchoring, premium pre-scan/progress polish, and broader Pi assistant model choices.
|
| 28 |
- **v161** fixes duplicate delete modal triggers and stuck `Deleting…` states with single-flight delete guards.
|
| 29 |
|
| 30 |
-
---
|
| 31 |
-
title: Agentic Space Factory
|
| 32 |
-
sdk: docker
|
| 33 |
-
hf_oauth: true
|
| 34 |
-
hf_oauth_expiration_minutes: 480
|
| 35 |
-
hf_oauth_scopes:
|
| 36 |
-
- read-repos
|
| 37 |
-
- write-repos
|
| 38 |
-
- manage-repos
|
| 39 |
-
- gated-repos
|
| 40 |
-
- inference-api
|
| 41 |
-
- jobs
|
| 42 |
-
- read-billing
|
| 43 |
-
---
|
| 44 |
-
|
| 45 |
# Agentic Space Factory
|
| 46 |
|
| 47 |
Agentic Space Factory turns a Hugging Face model card into a **private, testable Gradio Space** using a Hugging Face Job, Pi, a coding model through Hugging Face Inference Providers, and a private Storage Bucket for run state, traces, reports, generated files, and validation artifacts.
|
|
|
|
| 13 |
- read-billing
|
| 14 |
---
|
| 15 |
|
| 16 |
+
## v175 — Anonymous cross-run evaluation archive
|
| 17 |
+
|
| 18 |
+
- Adds an optional operator-owned evaluation bucket mounted into Jobs, separate from each user's private run bucket.
|
| 19 |
+
- Workers publish `eval_record.json` plus a compact event timeline with hashed run/user/Space identifiers, structured hardware/Pi/recovery/validation metrics, and no raw generated code, prompts, tokens, or private bucket paths.
|
| 20 |
+
- Controlled by `ASF_EVAL_ENABLED`, `ASF_EVAL_BUCKET_SOURCE`, `ASF_EVAL_BUCKET_PATH`, `ASF_EVAL_BUCKET_MOUNT`, and `ASF_EVAL_SALT`.
|
| 21 |
+
- The Run storage card now indicates whether anonymous project evaluation is enabled for the instance.
|
| 22 |
+
|
| 23 |
+
## v174 — Bucket run-prefix mount and robust worker bootstrap writes
|
| 24 |
+
|
| 25 |
+
- Mounts only the `runs/` bucket prefix into Jobs at `/output/runs`, while the worker still writes to `/output/runs/<run_id>/...`.
|
| 26 |
+
- Keeps API-side writes on canonical `hf://buckets/<namespace>/<bucket>/runs/<run_id>/...` object URIs, with `HfFileSystem` attempts followed by a `sync_bucket` fallback for fresh prefixes.
|
| 27 |
+
- Removes the v172 parent-prefix `makedirs()` workaround, because Bucket prefixes are virtual object paths rather than git-style folders.
|
| 28 |
+
- Requires `huggingface_hub[oauth]>=1.11.0` so Buckets, Jobs volumes and sync helpers are available in fresh installs.
|
| 29 |
+
|
| 30 |
+
## v172 — Fresh bucket writes and pre-scan polish
|
| 31 |
+
|
| 32 |
+
- Keeps the Hugging Face Space metadata at the very top of `README.md`, so the app cannot boot with a configuration error after archive edits.
|
| 33 |
+
- Makes Bucket writes resilient for fresh run prefixes by creating parent prefixes before writing `_worker.py`, launch metadata, state, summaries, and events.
|
| 34 |
+
- Refreshes the Model pre-scan card into a calmer status panel with compact metadata chips and less oversized green treatment.
|
| 35 |
|
| 36 |
## v170 — Real bucket recursive run deletion
|
| 37 |
|
|
|
|
| 46 |
- **v165** fixes fresh-install recovery failures, README metadata preservation, timeline failure anchoring, premium pre-scan/progress polish, and broader Pi assistant model choices.
|
| 47 |
- **v161** fixes duplicate delete modal triggers and stuck `Deleting…` states with single-flight delete guards.
|
| 48 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 49 |
# Agentic Space Factory
|
| 50 |
|
| 51 |
Agentic Space Factory turns a Hugging Face model card into a **private, testable Gradio Space** using a Hugging Face Job, Pi, a coding model through Hugging Face Inference Providers, and a private Storage Bucket for run state, traces, reports, generated files, and validation artifacts.
|
app.py
CHANGED
|
@@ -250,6 +250,14 @@ def register_custom_routes(fastapi_app: FastAPI) -> None:
|
|
| 250 |
"user": {"username": ctx["username"], "missing_scopes": ctx.get("missing_scopes", []), "warnings": ctx.get("warnings", [])} if ctx else None,
|
| 251 |
"login_url": "/oauth/huggingface/login",
|
| 252 |
"logout_url": "/oauth/huggingface/logout",
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 253 |
}
|
| 254 |
)
|
| 255 |
|
|
@@ -269,6 +277,14 @@ def register_custom_routes(fastapi_app: FastAPI) -> None:
|
|
| 269 |
"scopes": ctx.get("scopes", []),
|
| 270 |
"missing_scopes": ctx.get("missing_scopes", []),
|
| 271 |
"warnings": ctx.get("warnings", []),
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 272 |
"expires_at": ctx.get("expires_at"),
|
| 273 |
"login_url": "/oauth/huggingface/login",
|
| 274 |
"logout_url": "/oauth/huggingface/logout",
|
|
@@ -686,7 +702,8 @@ def _safe_url(url: str | None) -> str:
|
|
| 686 |
def _run_artifacts_url(run_id: str | None, bucket_source: str | None) -> str:
|
| 687 |
if not run_id or not bucket_source:
|
| 688 |
return ""
|
| 689 |
-
|
|
|
|
| 690 |
|
| 691 |
|
| 692 |
def _button_link(label: str, url: str | None):
|
|
|
|
| 250 |
"user": {"username": ctx["username"], "missing_scopes": ctx.get("missing_scopes", []), "warnings": ctx.get("warnings", [])} if ctx else None,
|
| 251 |
"login_url": "/oauth/huggingface/login",
|
| 252 |
"logout_url": "/oauth/huggingface/logout",
|
| 253 |
+
"anonymous_eval": {
|
| 254 |
+
"enabled": bool(settings.eval_enabled and settings.eval_bucket_source),
|
| 255 |
+
"bucket_source": settings.eval_bucket_source if settings.eval_enabled else "",
|
| 256 |
+
"bucket_path": settings.eval_bucket_path if settings.eval_enabled else "",
|
| 257 |
+
"job_mount_path": settings.eval_bucket_mount if settings.eval_enabled else "",
|
| 258 |
+
"stores_generated_code": False,
|
| 259 |
+
"stores_raw_prompts": False,
|
| 260 |
+
},
|
| 261 |
}
|
| 262 |
)
|
| 263 |
|
|
|
|
| 277 |
"scopes": ctx.get("scopes", []),
|
| 278 |
"missing_scopes": ctx.get("missing_scopes", []),
|
| 279 |
"warnings": ctx.get("warnings", []),
|
| 280 |
+
"anonymous_eval": {
|
| 281 |
+
"enabled": bool(settings.eval_enabled and settings.eval_bucket_source),
|
| 282 |
+
"bucket_source": settings.eval_bucket_source if settings.eval_enabled else "",
|
| 283 |
+
"bucket_path": settings.eval_bucket_path if settings.eval_enabled else "",
|
| 284 |
+
"job_mount_path": settings.eval_bucket_mount if settings.eval_enabled else "",
|
| 285 |
+
"stores_generated_code": False,
|
| 286 |
+
"stores_raw_prompts": False,
|
| 287 |
+
},
|
| 288 |
"expires_at": ctx.get("expires_at"),
|
| 289 |
"login_url": "/oauth/huggingface/login",
|
| 290 |
"logout_url": "/oauth/huggingface/logout",
|
|
|
|
| 702 |
def _run_artifacts_url(run_id: str | None, bucket_source: str | None) -> str:
|
| 703 |
if not run_id or not bucket_source:
|
| 704 |
return ""
|
| 705 |
+
prefix = settings.bucket_runs_prefix.strip().strip("/") or "runs"
|
| 706 |
+
return f"https://huggingface.co/buckets/{bucket_source}/tree/{prefix}/{run_id}"
|
| 707 |
|
| 708 |
|
| 709 |
def _button_link(label: str, url: str | None):
|
pyproject.toml
CHANGED
|
@@ -5,7 +5,7 @@ description = "Public-preview Hugging Face-native Agentic Space Factory"
|
|
| 5 |
requires-python = ">=3.11"
|
| 6 |
dependencies = [
|
| 7 |
"gradio>=5.0.0",
|
| 8 |
-
"huggingface_hub>=1.
|
| 9 |
"pydantic>=2.0.0",
|
| 10 |
"python-dateutil>=2.9.0",
|
| 11 |
]
|
|
|
|
| 5 |
requires-python = ">=3.11"
|
| 6 |
dependencies = [
|
| 7 |
"gradio>=5.0.0",
|
| 8 |
+
"huggingface_hub[oauth]>=1.11.0",
|
| 9 |
"pydantic>=2.0.0",
|
| 10 |
"python-dateutil>=2.9.0",
|
| 11 |
]
|
requirements.txt
CHANGED
|
@@ -1,5 +1,5 @@
|
|
| 1 |
gradio>=5.0.0
|
| 2 |
-
huggingface_hub[oauth]>=1.
|
| 3 |
pydantic>=2.0.0
|
| 4 |
python-dateutil>=2.9.0
|
| 5 |
uvicorn>=0.30.0
|
|
|
|
| 1 |
gradio>=5.0.0
|
| 2 |
+
huggingface_hub[oauth]>=1.11.0
|
| 3 |
pydantic>=2.0.0
|
| 4 |
python-dateutil>=2.9.0
|
| 5 |
uvicorn>=0.30.0
|