fffiloni commited on
Commit
0ac935a
Β·
verified Β·
1 Parent(s): 6ade560

Upload 5 files

Browse files
Files changed (3) hide show
  1. CHANGELOG.md +7 -0
  2. README.md +7 -1
  3. app.py +102 -6
CHANGELOG.md CHANGED
@@ -19,3 +19,10 @@
19
 
20
  - Confirmed Gradio Client auth compatibility helper.
21
  - Improved stdout logging for worker events.
 
 
 
 
 
 
 
 
19
 
20
  - Confirmed Gradio Client auth compatibility helper.
21
  - Improved stdout logging for worker events.
22
+
23
+ ## v4 β€” Pi gist recipe
24
+
25
+ - Added Phase 4 tab: Pi reads the HF Spaces Agent Quickstart gist and is asked to use the `hf` CLI to create/upload a private target Space.
26
+ - Added a new `pi_gist_recipe` worker payload.
27
+ - The wrapper still performs independent final validation through the live Gradio API before declaring success.
28
+ - Saved artifacts include `generated/GOAL.md`, optional `generated/PI_SUMMARY.md`, Pi logs, traces, API schema, and API test result.
README.md CHANGED
@@ -18,7 +18,7 @@ hf_oauth_scopes:
18
  - jobs
19
  ---
20
 
21
- # Agentic Space Factory β€” V3 Pi Smoke
22
 
23
  This version validates the safe foundation for a Hugging Face-native β€œAgentic Space Factory”.
24
 
@@ -115,6 +115,7 @@ For local UI development, the app can render, but launching a Job requires a rea
115
 
116
 
117
  ## Phase 3 β€” Pi smoke test
 
118
 
119
  This phase installs `@mariozechner/pi-coding-agent` inside the HF Job, configures Pi with Hugging Face Inference Providers using the OAuth token, and asks Pi to make one safe edit to a generated Gradio app before creating the private target Space.
120
 
@@ -129,3 +130,8 @@ runs/<run_id>/tests/test_result.json
129
  ```
130
 
131
  The target Space remains private by default. Success is only declared after the live Gradio API returns the expected Pi-modified output.
 
 
 
 
 
 
18
  - jobs
19
  ---
20
 
21
+ # Agentic Space Factory β€” V4 Pi Gist Recipe
22
 
23
  This version validates the safe foundation for a Hugging Face-native β€œAgentic Space Factory”.
24
 
 
115
 
116
 
117
  ## Phase 3 β€” Pi smoke test
118
+ - Phase 4 β€” Pi gist recipe
119
 
120
  This phase installs `@mariozechner/pi-coding-agent` inside the HF Job, configures Pi with Hugging Face Inference Providers using the OAuth token, and asks Pi to make one safe edit to a generated Gradio app before creating the private target Space.
121
 
 
130
  ```
131
 
132
  The target Space remains private by default. Success is only declared after the live Gradio API returns the expected Pi-modified output.
133
+
134
+
135
+ ## Phase 4
136
+
137
+ Phase 4 asks Pi to follow the HF Spaces Agent Quickstart gist and use the `hf` CLI inside an HF Job to create/upload a private Space. The wrapper independently validates the live Gradio API before reporting success.
app.py CHANGED
@@ -12,6 +12,7 @@ from src.jobs import (
12
  inspect_job_safe,
13
  launch_create_private_space_job,
14
  launch_hello_job,
 
15
  launch_pi_space_smoke_job,
16
  )
17
  from src.runs import make_run_id, validate_run_id
@@ -19,7 +20,7 @@ from src.security import redact
19
 
20
 
21
  APP_DESCRIPTION = f"""
22
- # Agentic Space Factory β€” V3 Pi Smoke
23
 
24
  This version validates the two critical foundations:
25
 
@@ -27,6 +28,7 @@ This version validates the two critical foundations:
27
  Phase 1: HF OAuth β†’ HF Job β†’ mounted private Bucket β†’ run state/events/report β†’ UI readback
28
  Phase 2: HF OAuth β†’ HF Job β†’ private target Space β†’ file upload β†’ live Gradio API validation β†’ Bucket report
29
  Phase 3: HF OAuth β†’ HF Job β†’ Pi modifies app.py β†’ private target Space β†’ live API validation β†’ Pi traces
 
30
  ```
31
 
32
  Configured bucket: `{settings.bucket_uri}`
@@ -69,6 +71,38 @@ def propose_pi_run_id() -> str:
69
  return make_run_id("pi")
70
 
71
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
  def launch_pi_space_job_ui(
73
  requested_run_id: str,
74
  target_space_name: str,
@@ -173,6 +207,68 @@ def build_demo() -> gr.Blocks:
173
  login_status = gr.Markdown()
174
  demo.load(fn=get_login_status, inputs=None, outputs=login_status)
175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
177
  with gr.Tab("Phase 3 β€” Pi smoke test"):
178
  gr.Markdown(
@@ -328,12 +424,12 @@ It will fail safely if the target Space already exists, to avoid overwriting use
328
  """
329
  ## Next increments
330
 
331
- After Phase 2 passes, the next step is Phase 3:
332
 
333
- 1. install and configure Pi inside the Job,
334
- 2. ask Pi to modify/repair the simple target Space,
335
- 3. collect Pi traces into the bucket,
336
- 4. keep the same live API validation gate.
337
  """
338
  )
339
 
 
12
  inspect_job_safe,
13
  launch_create_private_space_job,
14
  launch_hello_job,
15
+ launch_pi_gist_recipe_job,
16
  launch_pi_space_smoke_job,
17
  )
18
  from src.runs import make_run_id, validate_run_id
 
20
 
21
 
22
  APP_DESCRIPTION = f"""
23
+ # Agentic Space Factory β€” V4 Pi Gist Recipe
24
 
25
  This version validates the two critical foundations:
26
 
 
28
  Phase 1: HF OAuth β†’ HF Job β†’ mounted private Bucket β†’ run state/events/report β†’ UI readback
29
  Phase 2: HF OAuth β†’ HF Job β†’ private target Space β†’ file upload β†’ live Gradio API validation β†’ Bucket report
30
  Phase 3: HF OAuth β†’ HF Job β†’ Pi modifies app.py β†’ private target Space β†’ live API validation β†’ Pi traces
31
+ Phase 4: HF OAuth β†’ HF Job β†’ Pi reads gist β†’ uses hf CLI β†’ private Space β†’ wrapper live API validation
32
  ```
33
 
34
  Configured bucket: `{settings.bucket_uri}`
 
71
  return make_run_id("pi")
72
 
73
 
74
+ def propose_gist_run_id() -> str:
75
+ return make_run_id("gist")
76
+
77
+
78
+ def launch_pi_gist_job_ui(
79
+ requested_run_id: str,
80
+ target_space_name: str,
81
+ pi_model: str,
82
+ profile: gr.OAuthProfile | None,
83
+ oauth_token: gr.OAuthToken | None,
84
+ ) -> tuple[str, str, str, str, str, str]:
85
+ username = _profile_username(profile)
86
+ token = _token_value(oauth_token)
87
+ if not username or not token:
88
+ raise gr.Error("Please sign in with Hugging Face first. OAuth profile/token is missing.")
89
+
90
+ run_id = validate_run_id(requested_run_id or propose_gist_run_id())
91
+ result = launch_pi_gist_recipe_job(
92
+ token=token,
93
+ username=username,
94
+ target_slug=target_space_name,
95
+ pi_model=pi_model,
96
+ run_id=run_id,
97
+ )
98
+
99
+ job_url = result.get("job_url") or ""
100
+ target_space = result.get("target_space") or ""
101
+ target_url = result.get("target_space_url") or ""
102
+ summary = json.dumps(result, indent=2)
103
+ return run_id, result["job_id"], job_url, target_space, target_url, summary
104
+
105
+
106
  def launch_pi_space_job_ui(
107
  requested_run_id: str,
108
  target_space_name: str,
 
207
  login_status = gr.Markdown()
208
  demo.load(fn=get_login_status, inputs=None, outputs=login_status)
209
 
210
+ with gr.Tab("Phase 4 β€” Pi gist recipe"):
211
+ gr.Markdown(
212
+ """
213
+ This phase is the first closer reproduction of the article workflow. The HF Job installs Pi, gives it the HF Spaces Agent Quickstart gist, and asks Pi to use the `hf` CLI to create/upload a **private** target Space.
214
+
215
+ The wrapper still stays in control of final success: it independently checks that the target Space exists and validates the live Gradio API.
216
+
217
+ Use a fresh Space name. This phase intentionally fails if the target Space already exists.
218
+ """
219
+ )
220
+ with gr.Row():
221
+ gist_run_id_box = gr.Textbox(label="Run ID", value=propose_gist_run_id, interactive=True)
222
+ new_gist_run_btn = gr.Button("Generate new run id")
223
+ new_gist_run_btn.click(fn=propose_gist_run_id, inputs=None, outputs=gist_run_id_box)
224
+
225
+ gist_target_space_name = gr.Textbox(
226
+ label="Target Space name",
227
+ placeholder="e.g. space-factory-pi-gist-v1",
228
+ info="Use a new name. Pi is asked to create this private Space under your username using hf CLI.",
229
+ )
230
+ gist_model_box = gr.Textbox(
231
+ label="Pi model",
232
+ value="moonshotai/Kimi-K2.5",
233
+ info="Model used by Pi through Hugging Face Inference Providers.",
234
+ )
235
+ launch_gist_btn = gr.Button("Run Pi gist recipe", variant="primary")
236
+
237
+ phase4_job_id_box = gr.Textbox(label="Job ID", interactive=True)
238
+ phase4_job_url_box = gr.Textbox(label="Job URL", interactive=False)
239
+ phase4_target_space_box = gr.Textbox(label="Target Space", interactive=False)
240
+ phase4_target_url_box = gr.Textbox(label="Target Space URL", interactive=False)
241
+ phase4_launch_result = gr.Code(label="Launch result", language="json")
242
+
243
+ launch_gist_btn.click(
244
+ fn=launch_pi_gist_job_ui,
245
+ inputs=[gist_run_id_box, gist_target_space_name, gist_model_box],
246
+ outputs=[
247
+ gist_run_id_box,
248
+ phase4_job_id_box,
249
+ phase4_job_url_box,
250
+ phase4_target_space_box,
251
+ phase4_target_url_box,
252
+ phase4_launch_result,
253
+ ],
254
+ )
255
+
256
+ phase4_refresh_btn = gr.Button("Refresh Phase 4 run status")
257
+ with gr.Tab("Phase 4 state"):
258
+ phase4_state_code = gr.Code(label="state.json", language="json")
259
+ with gr.Tab("Phase 4 events"):
260
+ phase4_events_code = gr.Code(label="events.jsonl", language="json")
261
+ with gr.Tab("Phase 4 report"):
262
+ phase4_report_md = gr.Markdown()
263
+ with gr.Tab("Phase 4 job"):
264
+ phase4_job_code = gr.Code(label="Job status/logs", language="json")
265
+
266
+ phase4_refresh_btn.click(
267
+ fn=refresh_run_ui,
268
+ inputs=[gist_run_id_box, phase4_job_id_box],
269
+ outputs=[phase4_state_code, phase4_events_code, phase4_report_md, phase4_job_code],
270
+ )
271
+
272
 
273
  with gr.Tab("Phase 3 β€” Pi smoke test"):
274
  gr.Markdown(
 
424
  """
425
  ## Next increments
426
 
427
+ After Phase 4 passes, the next step is Phase 5:
428
 
429
+ 1. analyze a real model card,
430
+ 2. choose a small template,
431
+ 3. let Pi apply the same gist-style loop,
432
+ 4. keep the wrapper-owned live API validation gate.
433
  """
434
  )
435