tc043 Codex commited on
Commit
473cb68
·
1 Parent(s): eae9568

feat: add extensive test suite and debugging utilities for Gradio app API validation

Browse files
app.py CHANGED
@@ -7,6 +7,15 @@ load_dotenv()
7
 
8
  import gradio as gr
9
 
 
 
 
 
 
 
 
 
 
10
  ROOT = Path(__file__).parent
11
  GRAMMAR_PATH = ROOT / "grammar.gbnf"
12
 
@@ -68,9 +77,11 @@ def is_semantic_repeat(new_task: str, history: list) -> bool:
68
  return True
69
  return False
70
 
71
- async def generate_atomic_task(goal: str, previous_failures: int, history: list = None, rejected_task: str = None) -> str:
72
  if history is None:
73
  history = []
 
 
74
 
75
  recent_history = history[-3:] if history else []
76
  history_str = "\n".join([f"- {t}" for t in recent_history]) if recent_history else "None"
@@ -85,7 +96,11 @@ async def generate_atomic_task(goal: str, previous_failures: int, history: list
85
  ]
86
  if previous_failures == 1:
87
  return "Move your mouse to the browser icon."
88
- return demo_steps[min(len(history), len(demo_steps) - 1)]
 
 
 
 
89
 
90
  else:
91
  # If a task was rejected as too hard, route to MiniCPM to break it down further
@@ -124,16 +139,20 @@ async def generate_atomic_task(goal: str, previous_failures: int, history: list
124
  content = response['choices'][0]['text'].strip()
125
 
126
  # Check if output is empty or a repetition
127
- is_invalid = not content or is_semantic_repeat(content, history)
128
 
129
  if is_invalid:
130
  print(f"NEMOTRON OUTPUT INVALID OR REPETITION ('{content}'). FALLING BACK TO MINICPM...", flush=True)
131
  last_task = history[-1] if history else ""
 
 
132
  user_content = f"Goal: {goal}\nCompleted Tasks: {history_str}\nFailures: {previous_failures}\n"
133
- if last_task:
134
- user_content += f"CRITICAL: Do NOT output '{last_task}'. Output the strictly NEXT new physical step."
 
 
135
  else:
136
- user_content += "Output the NEXT step."
137
 
138
  messages = [
139
  {"role": "system", "content": "You are a cognitive pacemaker. Focus strictly on the physical goal and break it down into an extremely tiny, atomic physical action under 8 words. Ignore mental blocks or feelings of being stuck and output ONLY the single physical action step."},
@@ -264,6 +283,7 @@ async def process_step(state, action: str, goal: str = None, style: str = None,
264
  state["too_hard_count"] = 0
265
  state["history"] = []
266
  state["raw_history"] = []
 
267
  state["trace"] = [{"event": "start", "goal": state["goal"], "style": state["style"]}]
268
 
269
  elif action == "too_hard":
@@ -276,6 +296,10 @@ async def process_step(state, action: str, goal: str = None, style: str = None,
276
 
277
  elif action == "skip":
278
  append_trace(state, {"event": "skip", "task": state["current_task"]})
 
 
 
 
279
  # Note: Do not increment too_hard_count
280
 
281
  elif action == "done":
@@ -291,7 +315,7 @@ async def process_step(state, action: str, goal: str = None, style: str = None,
291
  state["current_task"] = breaker_task
292
  append_trace(state, {"event": "circuit_breaker", "task": breaker_task})
293
  state["too_hard_count"] = 0 # Reset after breaking
294
- return state, generate_task_html(breaker_task), generate_breadcrumbs_html(state["history"][-3:]), gr.update(visible=False)
295
 
296
  # Standard Loop
297
  rejected_task = state["current_task"] if state["too_hard_count"] > 0 else None
@@ -300,6 +324,7 @@ async def process_step(state, action: str, goal: str = None, style: str = None,
300
  state["goal"],
301
  state["too_hard_count"],
302
  history=state["raw_history"],
 
303
  rejected_task=rejected_task,
304
  )
305
  styled_task = await apply_activation_style(raw_task, state["style"])
@@ -314,7 +339,7 @@ async def process_step(state, action: str, goal: str = None, style: str = None,
314
  "too_hard_count": state["too_hard_count"],
315
  })
316
 
317
- return state, generate_task_html(styled_task), generate_breadcrumbs_html(state["history"][-3:]), gr.update(visible=True)
318
 
319
  with gr.Blocks(css=custom_css, title="Step-Zero") as app:
320
  session_state = gr.State()
@@ -351,10 +376,10 @@ with gr.Blocks(css=custom_css, title="Step-Zero") as app:
351
 
352
  # Temporary Loading State Function
353
  def show_loading():
354
- return gr.update(visible=False), gr.update(visible=True), generate_task_html("<span class='text-gray-600 animate-pulse'>Calculating constraint...</span>", animate=False), gr.update(visible=False)
355
 
356
  def show_loading_step():
357
- return generate_task_html("<span class='text-gray-600 animate-pulse'>Loading next step...</span>", animate=False), gr.update(visible=False)
358
 
359
  # --- Event Handlers ---
360
 
@@ -426,7 +451,7 @@ with gr.Blocks(css=custom_css, title="Step-Zero") as app:
426
  with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".json") as f:
427
  json.dump(state.get("trace", []), f, indent=2)
428
  filepath = f.name
429
- return gr.update(value=filepath, visible=True)
430
 
431
  btn_trace.click(
432
  fn=export_trace_fn,
@@ -441,6 +466,7 @@ with gr.Blocks(css=custom_css, title="Step-Zero") as app:
441
  from huggingface_hub import HfApi
442
 
443
  try:
 
444
  with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".json") as f:
445
  json.dump(state.get("trace", []), f, indent=2)
446
  filepath = f.name
@@ -455,9 +481,9 @@ with gr.Blocks(css=custom_css, title="Step-Zero") as app:
455
  repo_id="tc043/step-zero-dataset",
456
  repo_type="dataset"
457
  )
458
- return gr.update(value="<span class='text-green-500'>✓ Successfully pushed trace to HF Hub!</span>", visible=True)
459
  except Exception as e:
460
- return gr.update(value=f"<span class='text-red-500'>Error pushing to Hub: {str(e)}</span>", visible=True)
461
 
462
  btn_push.click(
463
  fn=push_to_hub_fn,
 
7
 
8
  import gradio as gr
9
 
10
+ # --- Gradio 5.x BugFix Monkeypatch ---
11
+ import gradio_client.utils as client_utils
12
+ _original_json_schema_to_python_type = client_utils._json_schema_to_python_type
13
+ def _safe_json_schema_to_python_type(schema, defs=None):
14
+ if isinstance(schema, bool):
15
+ return "Any"
16
+ return _original_json_schema_to_python_type(schema, defs)
17
+ client_utils._json_schema_to_python_type = _safe_json_schema_to_python_type
18
+ # -------------------------------------
19
  ROOT = Path(__file__).parent
20
  GRAMMAR_PATH = ROOT / "grammar.gbnf"
21
 
 
77
  return True
78
  return False
79
 
80
+ async def generate_atomic_task(goal: str, previous_failures: int, history: list = None, skipped_history: list = None, rejected_task: str = None) -> str:
81
  if history is None:
82
  history = []
83
+ if skipped_history is None:
84
+ skipped_history = []
85
 
86
  recent_history = history[-3:] if history else []
87
  history_str = "\n".join([f"- {t}" for t in recent_history]) if recent_history else "None"
 
96
  ]
97
  if previous_failures == 1:
98
  return "Move your mouse to the browser icon."
99
+ if previous_failures == 2:
100
+ return "Put your hand on the mouse."
101
+
102
+ total_steps = len(history) + len(skipped_history)
103
+ return demo_steps[min(total_steps, len(demo_steps) - 1)]
104
 
105
  else:
106
  # If a task was rejected as too hard, route to MiniCPM to break it down further
 
139
  content = response['choices'][0]['text'].strip()
140
 
141
  # Check if output is empty or a repetition
142
+ is_invalid = not content or is_semantic_repeat(content, history + skipped_history)
143
 
144
  if is_invalid:
145
  print(f"NEMOTRON OUTPUT INVALID OR REPETITION ('{content}'). FALLING BACK TO MINICPM...", flush=True)
146
  last_task = history[-1] if history else ""
147
+ last_skipped = skipped_history[-1] if skipped_history else ""
148
+
149
  user_content = f"Goal: {goal}\nCompleted Tasks: {history_str}\nFailures: {previous_failures}\n"
150
+ if last_skipped:
151
+ user_content += f"CRITICAL: The user explicitly skipped '{last_skipped}'. Do NOT output it again. Generate an ALTERNATIVE physical starting action.\n"
152
+ elif last_task:
153
+ user_content += f"CRITICAL: Do NOT output '{last_task}'. Output the strictly NEXT new physical step.\n"
154
  else:
155
+ user_content += "Output the NEXT step.\n"
156
 
157
  messages = [
158
  {"role": "system", "content": "You are a cognitive pacemaker. Focus strictly on the physical goal and break it down into an extremely tiny, atomic physical action under 8 words. Ignore mental blocks or feelings of being stuck and output ONLY the single physical action step."},
 
283
  state["too_hard_count"] = 0
284
  state["history"] = []
285
  state["raw_history"] = []
286
+ state["skipped_history"] = []
287
  state["trace"] = [{"event": "start", "goal": state["goal"], "style": state["style"]}]
288
 
289
  elif action == "too_hard":
 
296
 
297
  elif action == "skip":
298
  append_trace(state, {"event": "skip", "task": state["current_task"]})
299
+ if "skipped_history" not in state:
300
+ state["skipped_history"] = []
301
+ if state.get("current_raw_task"):
302
+ state["skipped_history"].append(state["current_raw_task"])
303
  # Note: Do not increment too_hard_count
304
 
305
  elif action == "done":
 
315
  state["current_task"] = breaker_task
316
  append_trace(state, {"event": "circuit_breaker", "task": breaker_task})
317
  state["too_hard_count"] = 0 # Reset after breaking
318
+ return state, generate_task_html(breaker_task), generate_breadcrumbs_html(state["history"][-3:]), gr.Row(visible=False)
319
 
320
  # Standard Loop
321
  rejected_task = state["current_task"] if state["too_hard_count"] > 0 else None
 
324
  state["goal"],
325
  state["too_hard_count"],
326
  history=state["raw_history"],
327
+ skipped_history=state.get("skipped_history", []),
328
  rejected_task=rejected_task,
329
  )
330
  styled_task = await apply_activation_style(raw_task, state["style"])
 
339
  "too_hard_count": state["too_hard_count"],
340
  })
341
 
342
+ return state, generate_task_html(styled_task), generate_breadcrumbs_html(state["history"][-3:]), gr.Row(visible=True)
343
 
344
  with gr.Blocks(css=custom_css, title="Step-Zero") as app:
345
  session_state = gr.State()
 
376
 
377
  # Temporary Loading State Function
378
  def show_loading():
379
+ return gr.Column(visible=False), gr.Column(visible=True), generate_task_html("<span class='text-gray-600 animate-pulse'>Calculating constraint...</span>", animate=False), gr.Row(visible=False)
380
 
381
  def show_loading_step():
382
+ return generate_task_html("<span class='text-gray-600 animate-pulse'>Loading next step...</span>", animate=False), gr.Row(visible=False)
383
 
384
  # --- Event Handlers ---
385
 
 
451
  with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".json") as f:
452
  json.dump(state.get("trace", []), f, indent=2)
453
  filepath = f.name
454
+ return gr.File(value=filepath, visible=True)
455
 
456
  btn_trace.click(
457
  fn=export_trace_fn,
 
466
  from huggingface_hub import HfApi
467
 
468
  try:
469
+ if not state: state = {}
470
  with tempfile.NamedTemporaryFile(mode="w", delete=False, suffix=".json") as f:
471
  json.dump(state.get("trace", []), f, indent=2)
472
  filepath = f.name
 
481
  repo_id="tc043/step-zero-dataset",
482
  repo_type="dataset"
483
  )
484
+ return gr.HTML(value="<span class='text-green-500'>✓ Successfully pushed trace to HF Hub!</span>", visible=True)
485
  except Exception as e:
486
+ return gr.HTML(value=f"<span class='text-red-500'>Error pushing to Hub: {str(e)}</span>", visible=True)
487
 
488
  btn_push.click(
489
  fn=push_to_hub_fn,
app_test.py ADDED
@@ -0,0 +1,379 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import asyncio
2
+ import json
3
+ import os
4
+ from pathlib import Path
5
+ from dotenv import load_dotenv
6
+ load_dotenv()
7
+
8
+ import gradio as gr
9
+
10
+ ROOT = Path(__file__).parent
11
+ GRAMMAR_PATH = ROOT / "grammar.gbnf"
12
+
13
+ # Keep the demo runnable while the GGUF files are still being prepared.
14
+ MOCK_MODE = os.getenv("STEP_ZERO_MOCK", "1") != "0"
15
+ NEMOTRON_MODEL_PATH = os.getenv("NEMOTRON_MODEL_PATH", "./models/step-zero-nemotron-finetuned.gguf")
16
+ MINICPM_MODEL_PATH = os.getenv("MINICPM_MODEL_PATH", "./models/minicpm-3-4b.gguf")
17
+
18
+ if not MOCK_MODE:
19
+ from llama_cpp import Llama
20
+ from llama_cpp import LlamaGrammar
21
+
22
+ grammar = LlamaGrammar.from_file(str(GRAMMAR_PATH))
23
+
24
+ # Use small context windows to save RAM.
25
+ nemotron = Llama(model_path=NEMOTRON_MODEL_PATH, n_ctx=1024)
26
+ minicpm = Llama(model_path=MINICPM_MODEL_PATH, n_ctx=1024)
27
+
28
+ # Per-model locks for concurrency
29
+ nemotron_lock = asyncio.Lock()
30
+ minicpm_lock = asyncio.Lock()
31
+
32
+ async def run_nemotron(func, *args, **kwargs):
33
+ async with nemotron_lock:
34
+ return await asyncio.to_thread(func, *args, **kwargs)
35
+
36
+ async def run_minicpm(func, *args, **kwargs):
37
+ async with minicpm_lock:
38
+ return await asyncio.to_thread(func, *args, **kwargs)
39
+
40
+ MAX_TRACE_EVENTS = 50
41
+ MAX_HISTORY_ITEMS = 20
42
+
43
+ def append_trace(state, event: dict) -> None:
44
+ state["trace"].append(event)
45
+ if len(state["trace"]) > MAX_TRACE_EVENTS:
46
+ state["trace"] = state["trace"][-MAX_TRACE_EVENTS:]
47
+
48
+ def append_history(state, displayed_task: str, raw_task: str) -> None:
49
+ state["history"].append(displayed_task)
50
+ state["raw_history"].append(raw_task)
51
+ if len(state["history"]) > MAX_HISTORY_ITEMS:
52
+ state["history"] = state["history"][-MAX_HISTORY_ITEMS:]
53
+ if len(state["raw_history"]) > MAX_HISTORY_ITEMS:
54
+ state["raw_history"] = state["raw_history"][-MAX_HISTORY_ITEMS:]
55
+
56
+ def is_semantic_repeat(new_task: str, history: list) -> bool:
57
+ if not history:
58
+ return False
59
+ new_words = set(new_task.lower().split())
60
+ if not new_words:
61
+ return False
62
+ for past in history[-3:]:
63
+ past_words = set(past.lower().split())
64
+ if not past_words:
65
+ continue
66
+ overlap = len(new_words & past_words) / max(len(new_words | past_words), 1)
67
+ if overlap > 0.7: # 70% word overlap = semantic repeat
68
+ return True
69
+ return False
70
+
71
+ async def generate_atomic_task(goal: str, previous_failures: int, history: list = None, rejected_task: str = None) -> str:
72
+ if history is None:
73
+ history = []
74
+
75
+ recent_history = history[-3:] if history else []
76
+ history_str = "\n".join([f"- {t}" for t in recent_history]) if recent_history else "None"
77
+
78
+ if MOCK_MODE:
79
+ await asyncio.sleep(1) # Simulate inference latency
80
+ demo_steps = [
81
+ "Open a new browser tab.",
82
+ "Create a blank document.",
83
+ "Write the first sentence.",
84
+ "Save the file.",
85
+ ]
86
+ if previous_failures == 1:
87
+ return "Move your mouse to the browser icon."
88
+ return demo_steps[min(len(history), len(demo_steps) - 1)]
89
+
90
+ else:
91
+ # If a task was rejected as too hard, route to MiniCPM to break it down further
92
+ if previous_failures > 0 and rejected_task:
93
+ print(f"TASK WAS REJECTED ('{rejected_task}'). ROUTING TO MINICPM FOR SUB-STEP BREAKDOWN...", flush=True)
94
+ messages = [
95
+ {"role": "system", "content": "You are a cognitive pacemaker. When a task is too hard, break it down into a single, even simpler, tiny physical starting action under 8 words. Return ONLY the starting action. CRITICAL: Focus strictly on the physical movement. Do NOT suggest thinking, planning, or remembering."},
96
+ {"role": "user", "content": f"The task '{rejected_task}' was too hard. Break it down into a single, even simpler physical starting action."}
97
+ ]
98
+ fallback_res = await run_minicpm(
99
+ minicpm.create_chat_completion,
100
+ messages=messages,
101
+ max_tokens=20,
102
+ temperature=0.1
103
+ )
104
+ content = fallback_res['choices'][0]['message']['content'].strip()
105
+ print(f"MINICPM BREAKDOWN OUT: {content}", flush=True)
106
+ content = content.strip('"\' ,.-1234567890)')
107
+ return content or "Focus on the screen."
108
+
109
+ # REAL INFERENCE using the exact string template used during fine-tuning
110
+ system_msg = "You are a cognitive pacemaker. Break down goals into extremely tiny, atomic physical actions under 8 words."
111
+
112
+ prompt = f"<extra_id_0>System\n{system_msg}\n\n"
113
+ prompt += f"<extra_id_1>User\nGoal: {goal}\nCompleted Tasks: {history_str}\nFailures: {previous_failures}\nOutput the NEXT step.\n"
114
+ prompt += f"<extra_id_1>Assistant\n"
115
+
116
+ response = await run_nemotron(
117
+ nemotron,
118
+ prompt,
119
+ max_tokens=20,
120
+ temperature=0.3,
121
+ stop=["\n", "<extra_id_1>"],
122
+ grammar=grammar # Enforcing grammar here!
123
+ )
124
+ content = response['choices'][0]['text'].strip()
125
+
126
+ # Check if output is empty or a repetition
127
+ is_invalid = not content or is_semantic_repeat(content, history)
128
+
129
+ if is_invalid:
130
+ print(f"NEMOTRON OUTPUT INVALID OR REPETITION ('{content}'). FALLING BACK TO MINICPM...", flush=True)
131
+ last_task = history[-1] if history else ""
132
+ user_content = f"Goal: {goal}\nCompleted Tasks: {history_str}\nFailures: {previous_failures}\n"
133
+ if last_task:
134
+ user_content += f"CRITICAL: Do NOT output '{last_task}'. Output the strictly NEXT new physical step."
135
+ else:
136
+ user_content += "Output the NEXT step."
137
+
138
+ messages = [
139
+ {"role": "system", "content": "You are a cognitive pacemaker. Focus strictly on the physical goal and break it down into an extremely tiny, atomic physical action under 8 words. Ignore mental blocks or feelings of being stuck and output ONLY the single physical action step."},
140
+ {"role": "user", "content": user_content}
141
+ ]
142
+ fallback_res = await run_minicpm(
143
+ minicpm.create_chat_completion,
144
+ messages=messages,
145
+ max_tokens=20,
146
+ temperature=0.1
147
+ )
148
+ content = fallback_res['choices'][0]['message']['content'].strip()
149
+ print(f"MINICPM FALLBACK OUT: {content}", flush=True)
150
+ else:
151
+ print(f"NEMOTRON RAW OUT: {content}", flush=True)
152
+
153
+ content = content.strip('"\' ,.-1234567890)')
154
+ return content or "Focus on the screen."
155
+
156
+ async def apply_activation_style(task: str, style="direct") -> str:
157
+ if MOCK_MODE:
158
+ await asyncio.sleep(0.5)
159
+ if style == "calm":
160
+ return f"When you are ready, {task[0].lower()}{task[1:]}"
161
+ if style == "encouraging":
162
+ return f"You can do this: {task}"
163
+ return f"{task} Now."
164
+
165
+ else:
166
+ # REAL INFERENCE
167
+ if style == "direct":
168
+ return f"{task.capitalize()}."
169
+
170
+ if style == "encouraging":
171
+ system_prompt = (
172
+ "You are a cognitive pacemaker. Rewrite the given task into an encouraging, supportive tone.\n"
173
+ "RULES:\n"
174
+ "1. Keep it as an action/command the user MUST do now. Start or end with an encouraging phrase like 'You got this!', 'Let's do it!', or 'Go ahead and...'.\n"
175
+ "2. Do NOT write in the past tense, do NOT congratulate the user, and do NOT treat the task as already completed.\n"
176
+ "3. Limit your response to EXACTLY ONE short sentence (under 12 words) and output ONLY the final rewritten task."
177
+ )
178
+ elif style == "calm":
179
+ system_prompt = (
180
+ "You are a cognitive pacemaker. Rewrite the given task into a calm, gentle tone.\n"
181
+ "RULES:\n"
182
+ "1. Keep it as an action/command. Use gentle prefixes like 'When you are ready, ...' or 'Take your time and ...'.\n"
183
+ "2. Do NOT write in the past tense and do NOT congratulate the user.\n"
184
+ "3. Limit your response to EXACTLY ONE short sentence (under 12 words) and output ONLY the final rewritten task."
185
+ )
186
+ else:
187
+ system_prompt = (
188
+ f"You are a cognitive pacemaker. Rewrite the given task into a {style} tone.\n"
189
+ "RULES:\n"
190
+ "1. Keep it as an action/command the user MUST do now.\n"
191
+ "2. Do NOT write in the past tense, do NOT congratulate the user, and do NOT treat the task as already completed.\n"
192
+ "3. Limit your response to EXACTLY ONE short sentence (under 12 words) and output ONLY the final rewritten task."
193
+ )
194
+
195
+ messages = [
196
+ {"role": "system", "content": system_prompt},
197
+ {"role": "user", "content": f"Task: {task}"}
198
+ ]
199
+ response = await run_minicpm(
200
+ minicpm.create_chat_completion,
201
+ messages=messages,
202
+ max_tokens=40,
203
+ temperature=0.2
204
+ )
205
+ content = response['choices'][0]['message']['content'].strip()
206
+ print(f"MINICPM RAW OUT: {content}", flush=True)
207
+ return content
208
+
209
+ # --- GRADIO UI ---
210
+
211
+ custom_css = """
212
+ body { background-color: #0a0a0a; color: #ffffff; font-family: 'Helvetica Neue', sans-serif; }
213
+ .gradio-container { background-color: transparent !important; border: none !important; }
214
+ footer { display: none !important; }
215
+ .fog { opacity: 0.3; filter: blur(2px); transition: all 0.5s ease; }
216
+ .fade-in { animation: fadeIn 0.5s ease-in forwards; }
217
+ @keyframes fadeIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: translateY(0); } }
218
+
219
+ /* Goal Input Styling */
220
+ #goal-input textarea {
221
+ background: transparent !important;
222
+ border: none !important;
223
+ border-bottom: 2px solid #4b5563 !important;
224
+ color: white !important;
225
+ font-size: 1.5rem !important;
226
+ text-align: center !important;
227
+ box-shadow: none !important;
228
+ border-radius: 0 !important;
229
+ }
230
+ #goal-input textarea:focus { border-bottom: 2px solid white !important; }
231
+
232
+ /* Buttons */
233
+ #btn-done { background-color: #16a34a !important; color: white !important; font-weight: bold; font-size: 1.25rem !important; }
234
+ #btn-skip { background-color: #4b5563 !important; color: white !important; font-weight: bold; font-size: 1.25rem !important; }
235
+ #btn-hard { background-color: #1f2937 !important; color: #d1d5db !important; font-weight: bold; font-size: 1.25rem !important; }
236
+ #btn-trace { background: transparent !important; border: none !important; color: #4b5563 !important; text-transform: uppercase; letter-spacing: 0.1em; font-size: 0.75rem !important; }
237
+ #btn-trace:hover { color: #d1d5db !important; }
238
+
239
+ /* Big Task Text */
240
+ #current-task { text-align: center; font-size: 3rem; font-weight: 800; min-height: 150px; display: flex; align-items: center; justify-content: center; }
241
+ @media (min-width: 768px) { #current-task { font-size: 4.5rem; } }
242
+ """
243
+
244
+ def generate_breadcrumbs_html(history: list) -> str:
245
+ html = "<div class='fog text-sm space-y-2'>"
246
+ for t in history:
247
+ html += f"<div>✓ {t}</div>"
248
+ html += "</div>"
249
+ return html
250
+
251
+ def generate_task_html(task: str, animate=True) -> str:
252
+ class_str = "fade-in" if animate else ""
253
+ return f"<div id='current-task' class='{class_str}'>{task}</div>"
254
+
255
+ async def process_step(state, action: str, goal: str = None, style: str = None, last_task: str = None):
256
+ if not state:
257
+ state = {}
258
+ # Initialization
259
+ if action == "start":
260
+ state["goal"] = goal
261
+ state["style"] = style
262
+ state["current_task"] = ""
263
+ state["current_raw_task"] = ""
264
+ state["too_hard_count"] = 0
265
+ state["history"] = []
266
+ state["raw_history"] = []
267
+ state["trace"] = [{"event": "start", "goal": state["goal"], "style": state["style"]}]
268
+
269
+ elif action == "too_hard":
270
+ state["too_hard_count"] += 1
271
+ append_trace(state, {
272
+ "event": "too_hard",
273
+ "task": state["current_task"],
274
+ "too_hard_count": state["too_hard_count"],
275
+ })
276
+
277
+ elif action == "skip":
278
+ append_trace(state, {"event": "skip", "task": state["current_task"]})
279
+ # Note: Do not increment too_hard_count
280
+
281
+ elif action == "done":
282
+ state["too_hard_count"] = 0
283
+ if last_task:
284
+ raw_task_done = state.get("current_raw_task") or last_task
285
+ append_history(state, last_task, raw_task_done)
286
+ append_trace(state, {"event": "done", "task": last_task})
287
+
288
+ # HARD CIRCUIT BREAKER
289
+ if state["too_hard_count"] >= 3:
290
+ breaker_task = "You are out of activation energy. Step away from the screen for 3 minutes. I will be here."
291
+ state["current_task"] = breaker_task
292
+ append_trace(state, {"event": "circuit_breaker", "task": breaker_task})
293
+ state["too_hard_count"] = 0 # Reset after breaking
294
+ return state, generate_task_html(breaker_task), generate_breadcrumbs_html(state["history"][-3:]), gr.update(visible=False)
295
+
296
+ # Standard Loop
297
+ rejected_task = state["current_task"] if state["too_hard_count"] > 0 else None
298
+
299
+ raw_task = await generate_atomic_task(
300
+ state["goal"],
301
+ state["too_hard_count"],
302
+ history=state["raw_history"],
303
+ rejected_task=rejected_task,
304
+ )
305
+ styled_task = await apply_activation_style(raw_task, state["style"])
306
+ state["current_task"] = styled_task
307
+ state["current_raw_task"] = raw_task
308
+
309
+ append_trace(state, {
310
+ "event": "generated_step",
311
+ "raw_task": raw_task,
312
+ "styled_task": styled_task,
313
+ "style": state["style"],
314
+ "too_hard_count": state["too_hard_count"],
315
+ })
316
+
317
+ return state, generate_task_html(styled_task), generate_breadcrumbs_html(state["history"][-3:]), gr.update(visible=True)
318
+
319
+ with gr.Blocks(css=custom_css, title="Step-Zero") as app:
320
+ session_state = gr.State()
321
+
322
+ with gr.Column(visible=True) as screen_start:
323
+ gr.HTML("<h1 class='text-4xl font-bold mb-8 text-center mt-20'>What is paralyzing you?</h1>")
324
+ goal_input = gr.Textbox(elem_id="goal-input", show_label=False, placeholder="e.g. Write my thesis...", lines=1)
325
+
326
+ with gr.Row(elem_classes="justify-center mt-8"):
327
+ style_radio = gr.Radio(
328
+ choices=["direct", "calm", "encouraging"],
329
+ value="direct",
330
+ show_label=False,
331
+ container=False
332
+ )
333
+
334
+ start_btn = gr.Button("Start", variant="primary", elem_classes="mt-8 mx-auto w-48")
335
+
336
+ with gr.Column(visible=False) as screen_task:
337
+ breadcrumbs_display = gr.HTML(elem_id="breadcrumbs-container")
338
+ task_display = gr.HTML(elem_id="task-container")
339
+
340
+ with gr.Row(elem_id="controls-container") as controls_row:
341
+ btn_done = gr.Button("I DID THIS", elem_id="btn-done")
342
+ btn_skip = gr.Button("SKIP", elem_id="btn-skip")
343
+ btn_hard = gr.Button("TOO HARD", elem_id="btn-hard")
344
+
345
+ with gr.Row(elem_classes="justify-center mt-4 gap-4"):
346
+ btn_trace = gr.Button("Export Trace", elem_id="btn-trace")
347
+ btn_push = gr.Button("Push to Hub", elem_id="btn-trace")
348
+
349
+ trace_download = gr.File(visible=False)
350
+ hub_status = gr.HTML(visible=False, elem_classes="text-center text-sm text-gray-400 mt-2")
351
+
352
+ # Temporary Loading State Function
353
+ def show_loading():
354
+ return gr.update(visible=False), gr.update(visible=True), generate_task_html("<span class='text-gray-600 animate-pulse'>Calculating constraint...</span>", animate=False), gr.update(visible=False)
355
+
356
+ def show_loading_step():
357
+ return generate_task_html("<span class='text-gray-600 animate-pulse'>Loading next step...</span>", animate=False), gr.update(visible=False)
358
+
359
+ # --- Event Handlers ---
360
+
361
+ async def handle_start(state, goal, style):
362
+ return await process_step(state, "start", goal=goal, style=style)
363
+
364
+ async def handle_done(state):
365
+ if not state: state = {}
366
+ return await process_step(state, "done", last_task=state.get("current_task"))
367
+
368
+ async def handle_skip(state):
369
+ return await process_step(state, "skip")
370
+
371
+ async def handle_too_hard(state):
372
+ return await process_step(state, "too_hard")
373
+
374
+ # Start Session
375
+ start_btn.click(
376
+ fn=show_loading,
377
+ outputs=[screen_start, screen_task, task_display, controls_row]
378
+ ).then(
379
+ fn=handle_start,
output.txt ADDED
@@ -0,0 +1,417 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ERROR: Exception in ASGI application
2
+ Traceback (most recent call last):
3
+ File "/usr/local/lib/python3.12/dist-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
4
+ result = await app( # type: ignore[func-returns-value]
5
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6
+ File "/usr/local/lib/python3.12/dist-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
7
+ return await self.app(scope, receive, send)
8
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
9
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/applications.py", line 1054, in __call__
10
+ await super().__call__(scope, receive, send)
11
+ File "/usr/local/lib/python3.12/dist-packages/starlette/applications.py", line 113, in __call__
12
+ await self.middleware_stack(scope, receive, send)
13
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 187, in __call__
14
+ raise exc
15
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 165, in __call__
16
+ await self.app(scope, receive, _send)
17
+ File "/usr/local/lib/python3.12/dist-packages/gradio/route_utils.py", line 789, in __call__
18
+ await self.app(scope, receive, send)
19
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/exceptions.py", line 62, in __call__
20
+ await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
21
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
22
+ raise exc
23
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
24
+ await app(scope, receive, sender)
25
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 715, in __call__
26
+ await self.middleware_stack(scope, receive, send)
27
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 735, in app
28
+ await route.handle(scope, receive, send)
29
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 288, in handle
30
+ await self.app(scope, receive, send)
31
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 76, in app
32
+ await wrap_app_handling_exceptions(app, request)(scope, receive, send)
33
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
34
+ raise exc
35
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
36
+ await app(scope, receive, sender)
37
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 73, in app
38
+ response = await f(request)
39
+ ^^^^^^^^^^^^^^^^
40
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 301, in app
41
+ raw_response = await run_endpoint_function(
42
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
43
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 214, in run_endpoint_function
44
+ return await run_in_threadpool(dependant.call, **values)
45
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
46
+ File "/usr/local/lib/python3.12/dist-packages/starlette/concurrency.py", line 39, in run_in_threadpool
47
+ return await anyio.to_thread.run_sync(func, *args)
48
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
49
+ File "/usr/local/lib/python3.12/dist-packages/anyio/to_thread.py", line 63, in run_sync
50
+ return await get_async_backend().run_sync_in_worker_thread(
51
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
52
+ File "/usr/local/lib/python3.12/dist-packages/anyio/_backends/_asyncio.py", line 2502, in run_sync_in_worker_thread
53
+ return await future
54
+ ^^^^^^^^^^^^
55
+ File "/usr/local/lib/python3.12/dist-packages/anyio/_backends/_asyncio.py", line 986, in run
56
+ result = context.run(func, *args)
57
+ ^^^^^^^^^^^^^^^^^^^^^^^^
58
+ File "/usr/local/lib/python3.12/dist-packages/gradio/routes.py", line 552, in main
59
+ gradio_api_info = api_info(request)
60
+ ^^^^^^^^^^^^^^^^^
61
+ File "/usr/local/lib/python3.12/dist-packages/gradio/routes.py", line 582, in api_info
62
+ api_info = utils.safe_deepcopy(app.get_blocks().get_api_info())
63
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
64
+ File "/usr/local/lib/python3.12/dist-packages/gradio/blocks.py", line 2992, in get_api_info
65
+ python_type = client_utils.json_schema_to_python_type(info)
66
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
67
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 920, in json_schema_to_python_type
68
+ type_ = _json_schema_to_python_type(schema, schema.get("$defs"))
69
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
70
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 975, in _json_schema_to_python_type
71
+ f"{n}: {_json_schema_to_python_type(v, defs)}{get_desc(v)}"
72
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
73
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 982, in _json_schema_to_python_type
74
+ f"str, {_json_schema_to_python_type(schema['additionalProperties'], defs)}"
75
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
76
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 928, in _json_schema_to_python_type
77
+ type_ = get_type(schema)
78
+ ^^^^^^^^^^^^^^^^
79
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 887, in get_type
80
+ if "const" in schema:
81
+ ^^^^^^^^^^^^^^^^^
82
+ TypeError: argument of type 'bool' is not iterable
83
+ ERROR: Exception in ASGI application
84
+ Traceback (most recent call last):
85
+ File "/usr/local/lib/python3.12/dist-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
86
+ result = await app( # type: ignore[func-returns-value]
87
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
88
+ File "/usr/local/lib/python3.12/dist-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
89
+ return await self.app(scope, receive, send)
90
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
91
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/applications.py", line 1054, in __call__
92
+ await super().__call__(scope, receive, send)
93
+ File "/usr/local/lib/python3.12/dist-packages/starlette/applications.py", line 113, in __call__
94
+ await self.middleware_stack(scope, receive, send)
95
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 187, in __call__
96
+ raise exc
97
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 165, in __call__
98
+ await self.app(scope, receive, _send)
99
+ File "/usr/local/lib/python3.12/dist-packages/gradio/route_utils.py", line 789, in __call__
100
+ await self.app(scope, receive, send)
101
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/exceptions.py", line 62, in __call__
102
+ await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
103
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
104
+ raise exc
105
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
106
+ await app(scope, receive, sender)
107
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 715, in __call__
108
+ await self.middleware_stack(scope, receive, send)
109
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 735, in app
110
+ await route.handle(scope, receive, send)
111
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 288, in handle
112
+ await self.app(scope, receive, send)
113
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 76, in app
114
+ await wrap_app_handling_exceptions(app, request)(scope, receive, send)
115
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
116
+ raise exc
117
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
118
+ await app(scope, receive, sender)
119
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 73, in app
120
+ response = await f(request)
121
+ ^^^^^^^^^^^^^^^^
122
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 301, in app
123
+ raw_response = await run_endpoint_function(
124
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
125
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 214, in run_endpoint_function
126
+ return await run_in_threadpool(dependant.call, **values)
127
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
128
+ File "/usr/local/lib/python3.12/dist-packages/starlette/concurrency.py", line 39, in run_in_threadpool
129
+ return await anyio.to_thread.run_sync(func, *args)
130
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
131
+ File "/usr/local/lib/python3.12/dist-packages/anyio/to_thread.py", line 63, in run_sync
132
+ return await get_async_backend().run_sync_in_worker_thread(
133
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
134
+ File "/usr/local/lib/python3.12/dist-packages/anyio/_backends/_asyncio.py", line 2502, in run_sync_in_worker_thread
135
+ return await future
136
+ ^^^^^^^^^^^^
137
+ File "/usr/local/lib/python3.12/dist-packages/anyio/_backends/_asyncio.py", line 986, in run
138
+ result = context.run(func, *args)
139
+ ^^^^^^^^^^^^^^^^^^^^^^^^
140
+ File "/usr/local/lib/python3.12/dist-packages/gradio/routes.py", line 552, in main
141
+ gradio_api_info = api_info(request)
142
+ ^^^^^^^^^^^^^^^^^
143
+ File "/usr/local/lib/python3.12/dist-packages/gradio/routes.py", line 582, in api_info
144
+ api_info = utils.safe_deepcopy(app.get_blocks().get_api_info())
145
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
146
+ File "/usr/local/lib/python3.12/dist-packages/gradio/blocks.py", line 2992, in get_api_info
147
+ python_type = client_utils.json_schema_to_python_type(info)
148
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
149
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 920, in json_schema_to_python_type
150
+ type_ = _json_schema_to_python_type(schema, schema.get("$defs"))
151
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
152
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 975, in _json_schema_to_python_type
153
+ f"{n}: {_json_schema_to_python_type(v, defs)}{get_desc(v)}"
154
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
155
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 982, in _json_schema_to_python_type
156
+ f"str, {_json_schema_to_python_type(schema['additionalProperties'], defs)}"
157
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
158
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 928, in _json_schema_to_python_type
159
+ type_ = get_type(schema)
160
+ ^^^^^^^^^^^^^^^^
161
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 887, in get_type
162
+ if "const" in schema:
163
+ ^^^^^^^^^^^^^^^^^
164
+ TypeError: argument of type 'bool' is not iterable
165
+ ERROR: Exception in ASGI application
166
+ Traceback (most recent call last):
167
+ File "/usr/local/lib/python3.12/dist-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
168
+ result = await app( # type: ignore[func-returns-value]
169
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
170
+ File "/usr/local/lib/python3.12/dist-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
171
+ return await self.app(scope, receive, send)
172
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
173
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/applications.py", line 1054, in __call__
174
+ await super().__call__(scope, receive, send)
175
+ File "/usr/local/lib/python3.12/dist-packages/starlette/applications.py", line 113, in __call__
176
+ await self.middleware_stack(scope, receive, send)
177
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 187, in __call__
178
+ raise exc
179
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 165, in __call__
180
+ await self.app(scope, receive, _send)
181
+ File "/usr/local/lib/python3.12/dist-packages/gradio/route_utils.py", line 789, in __call__
182
+ await self.app(scope, receive, send)
183
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/exceptions.py", line 62, in __call__
184
+ await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
185
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
186
+ raise exc
187
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
188
+ await app(scope, receive, sender)
189
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 715, in __call__
190
+ await self.middleware_stack(scope, receive, send)
191
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 735, in app
192
+ await route.handle(scope, receive, send)
193
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 288, in handle
194
+ await self.app(scope, receive, send)
195
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 76, in app
196
+ await wrap_app_handling_exceptions(app, request)(scope, receive, send)
197
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
198
+ raise exc
199
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
200
+ await app(scope, receive, sender)
201
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 73, in app
202
+ response = await f(request)
203
+ ^^^^^^^^^^^^^^^^
204
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 301, in app
205
+ raw_response = await run_endpoint_function(
206
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
207
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 214, in run_endpoint_function
208
+ return await run_in_threadpool(dependant.call, **values)
209
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
210
+ File "/usr/local/lib/python3.12/dist-packages/starlette/concurrency.py", line 39, in run_in_threadpool
211
+ return await anyio.to_thread.run_sync(func, *args)
212
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
213
+ File "/usr/local/lib/python3.12/dist-packages/anyio/to_thread.py", line 63, in run_sync
214
+ return await get_async_backend().run_sync_in_worker_thread(
215
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
216
+ File "/usr/local/lib/python3.12/dist-packages/anyio/_backends/_asyncio.py", line 2502, in run_sync_in_worker_thread
217
+ return await future
218
+ ^^^^^^^^^^^^
219
+ File "/usr/local/lib/python3.12/dist-packages/anyio/_backends/_asyncio.py", line 986, in run
220
+ result = context.run(func, *args)
221
+ ^^^^^^^^^^^^^^^^^^^^^^^^
222
+ File "/usr/local/lib/python3.12/dist-packages/gradio/routes.py", line 552, in main
223
+ gradio_api_info = api_info(request)
224
+ ^^^^^^^^^^^^^^^^^
225
+ File "/usr/local/lib/python3.12/dist-packages/gradio/routes.py", line 582, in api_info
226
+ api_info = utils.safe_deepcopy(app.get_blocks().get_api_info())
227
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
228
+ File "/usr/local/lib/python3.12/dist-packages/gradio/blocks.py", line 2992, in get_api_info
229
+ python_type = client_utils.json_schema_to_python_type(info)
230
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
231
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 920, in json_schema_to_python_type
232
+ type_ = _json_schema_to_python_type(schema, schema.get("$defs"))
233
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
234
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 975, in _json_schema_to_python_type
235
+ f"{n}: {_json_schema_to_python_type(v, defs)}{get_desc(v)}"
236
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
237
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 982, in _json_schema_to_python_type
238
+ f"str, {_json_schema_to_python_type(schema['additionalProperties'], defs)}"
239
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
240
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 928, in _json_schema_to_python_type
241
+ type_ = get_type(schema)
242
+ ^^^^^^^^^^^^^^^^
243
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 887, in get_type
244
+ if "const" in schema:
245
+ ^^^^^^^^^^^^^^^^^
246
+ TypeError: argument of type 'bool' is not iterable
247
+ ERROR: Exception in ASGI application
248
+ Traceback (most recent call last):
249
+ File "/usr/local/lib/python3.12/dist-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
250
+ result = await app( # type: ignore[func-returns-value]
251
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
252
+ File "/usr/local/lib/python3.12/dist-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
253
+ return await self.app(scope, receive, send)
254
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
255
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/applications.py", line 1054, in __call__
256
+ await super().__call__(scope, receive, send)
257
+ File "/usr/local/lib/python3.12/dist-packages/starlette/applications.py", line 113, in __call__
258
+ await self.middleware_stack(scope, receive, send)
259
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 187, in __call__
260
+ raise exc
261
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 165, in __call__
262
+ await self.app(scope, receive, _send)
263
+ File "/usr/local/lib/python3.12/dist-packages/gradio/route_utils.py", line 789, in __call__
264
+ await self.app(scope, receive, send)
265
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/exceptions.py", line 62, in __call__
266
+ await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
267
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
268
+ raise exc
269
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
270
+ await app(scope, receive, sender)
271
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 715, in __call__
272
+ await self.middleware_stack(scope, receive, send)
273
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 735, in app
274
+ await route.handle(scope, receive, send)
275
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 288, in handle
276
+ await self.app(scope, receive, send)
277
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 76, in app
278
+ await wrap_app_handling_exceptions(app, request)(scope, receive, send)
279
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
280
+ raise exc
281
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
282
+ await app(scope, receive, sender)
283
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 73, in app
284
+ response = await f(request)
285
+ ^^^^^^^^^^^^^^^^
286
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 301, in app
287
+ raw_response = await run_endpoint_function(
288
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
289
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 214, in run_endpoint_function
290
+ return await run_in_threadpool(dependant.call, **values)
291
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
292
+ File "/usr/local/lib/python3.12/dist-packages/starlette/concurrency.py", line 39, in run_in_threadpool
293
+ return await anyio.to_thread.run_sync(func, *args)
294
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
295
+ File "/usr/local/lib/python3.12/dist-packages/anyio/to_thread.py", line 63, in run_sync
296
+ return await get_async_backend().run_sync_in_worker_thread(
297
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
298
+ File "/usr/local/lib/python3.12/dist-packages/anyio/_backends/_asyncio.py", line 2502, in run_sync_in_worker_thread
299
+ return await future
300
+ ^^^^^^^^^^^^
301
+ File "/usr/local/lib/python3.12/dist-packages/anyio/_backends/_asyncio.py", line 986, in run
302
+ result = context.run(func, *args)
303
+ ^^^^^^^^^^^^^^^^^^^^^^^^
304
+ File "/usr/local/lib/python3.12/dist-packages/gradio/routes.py", line 552, in main
305
+ gradio_api_info = api_info(request)
306
+ ^^^^^^^^^^^^^^^^^
307
+ File "/usr/local/lib/python3.12/dist-packages/gradio/routes.py", line 582, in api_info
308
+ api_info = utils.safe_deepcopy(app.get_blocks().get_api_info())
309
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
310
+ File "/usr/local/lib/python3.12/dist-packages/gradio/blocks.py", line 2992, in get_api_info
311
+ python_type = client_utils.json_schema_to_python_type(info)
312
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
313
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 920, in json_schema_to_python_type
314
+ type_ = _json_schema_to_python_type(schema, schema.get("$defs"))
315
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
316
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 975, in _json_schema_to_python_type
317
+ f"{n}: {_json_schema_to_python_type(v, defs)}{get_desc(v)}"
318
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
319
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 982, in _json_schema_to_python_type
320
+ f"str, {_json_schema_to_python_type(schema['additionalProperties'], defs)}"
321
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
322
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 928, in _json_schema_to_python_type
323
+ type_ = get_type(schema)
324
+ ^^^^^^^^^^^^^^^^
325
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 887, in get_type
326
+ if "const" in schema:
327
+ ^^^^^^^^^^^^^^^^^
328
+ TypeError: argument of type 'bool' is not iterable
329
+ ERROR: Exception in ASGI application
330
+ Traceback (most recent call last):
331
+ File "/usr/local/lib/python3.12/dist-packages/uvicorn/protocols/http/httptools_impl.py", line 409, in run_asgi
332
+ result = await app( # type: ignore[func-returns-value]
333
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
334
+ File "/usr/local/lib/python3.12/dist-packages/uvicorn/middleware/proxy_headers.py", line 60, in __call__
335
+ return await self.app(scope, receive, send)
336
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
337
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/applications.py", line 1054, in __call__
338
+ await super().__call__(scope, receive, send)
339
+ File "/usr/local/lib/python3.12/dist-packages/starlette/applications.py", line 113, in __call__
340
+ await self.middleware_stack(scope, receive, send)
341
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 187, in __call__
342
+ raise exc
343
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/errors.py", line 165, in __call__
344
+ await self.app(scope, receive, _send)
345
+ File "/usr/local/lib/python3.12/dist-packages/gradio/route_utils.py", line 789, in __call__
346
+ await self.app(scope, receive, send)
347
+ File "/usr/local/lib/python3.12/dist-packages/starlette/middleware/exceptions.py", line 62, in __call__
348
+ await wrap_app_handling_exceptions(self.app, conn)(scope, receive, send)
349
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
350
+ raise exc
351
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
352
+ await app(scope, receive, sender)
353
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 715, in __call__
354
+ await self.middleware_stack(scope, receive, send)
355
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 735, in app
356
+ await route.handle(scope, receive, send)
357
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 288, in handle
358
+ await self.app(scope, receive, send)
359
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 76, in app
360
+ await wrap_app_handling_exceptions(app, request)(scope, receive, send)
361
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 53, in wrapped_app
362
+ raise exc
363
+ File "/usr/local/lib/python3.12/dist-packages/starlette/_exception_handler.py", line 42, in wrapped_app
364
+ await app(scope, receive, sender)
365
+ File "/usr/local/lib/python3.12/dist-packages/starlette/routing.py", line 73, in app
366
+ response = await f(request)
367
+ ^^^^^^^^^^^^^^^^
368
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 301, in app
369
+ raw_response = await run_endpoint_function(
370
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
371
+ File "/usr/local/lib/python3.12/dist-packages/fastapi/routing.py", line 214, in run_endpoint_function
372
+ return await run_in_threadpool(dependant.call, **values)
373
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
374
+ File "/usr/local/lib/python3.12/dist-packages/starlette/concurrency.py", line 39, in run_in_threadpool
375
+ return await anyio.to_thread.run_sync(func, *args)
376
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
377
+ File "/usr/local/lib/python3.12/dist-packages/anyio/to_thread.py", line 63, in run_sync
378
+ return await get_async_backend().run_sync_in_worker_thread(
379
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
380
+ File "/usr/local/lib/python3.12/dist-packages/anyio/_backends/_asyncio.py", line 2502, in run_sync_in_worker_thread
381
+ return await future
382
+ ^^^^^^^^^^^^
383
+ File "/usr/local/lib/python3.12/dist-packages/anyio/_backends/_asyncio.py", line 986, in run
384
+ result = context.run(func, *args)
385
+ ^^^^^^^^^^^^^^^^^^^^^^^^
386
+ File "/usr/local/lib/python3.12/dist-packages/gradio/routes.py", line 552, in main
387
+ gradio_api_info = api_info(request)
388
+ ^^^^^^^^^^^^^^^^^
389
+ File "/usr/local/lib/python3.12/dist-packages/gradio/routes.py", line 582, in api_info
390
+ api_info = utils.safe_deepcopy(app.get_blocks().get_api_info())
391
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
392
+ File "/usr/local/lib/python3.12/dist-packages/gradio/blocks.py", line 2992, in get_api_info
393
+ python_type = client_utils.json_schema_to_python_type(info)
394
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
395
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 920, in json_schema_to_python_type
396
+ type_ = _json_schema_to_python_type(schema, schema.get("$defs"))
397
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
398
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 975, in _json_schema_to_python_type
399
+ f"{n}: {_json_schema_to_python_type(v, defs)}{get_desc(v)}"
400
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
401
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 982, in _json_schema_to_python_type
402
+ f"str, {_json_schema_to_python_type(schema['additionalProperties'], defs)}"
403
+ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
404
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 928, in _json_schema_to_python_type
405
+ type_ = get_type(schema)
406
+ ^^^^^^^^^^^^^^^^
407
+ File "/usr/local/lib/python3.12/dist-packages/gradio_client/utils.py", line 887, in get_type
408
+ if "const" in schema:
409
+ ^^^^^^^^^^^^^^^^^
410
+ TypeError: argument of type 'bool' is not iterable
411
+ * Running on local URL: http://0.0.0.0:7860
412
+ Traceback (most recent call last):
413
+ File "/root/step-zero/app.py", line 470, in <module>
414
+ app.launch(server_name="0.0.0.0", server_port=7860)
415
+ File "/usr/local/lib/python3.12/dist-packages/gradio/blocks.py", line 2619, in launch
416
+ raise ValueError(
417
+ ValueError: When localhost is not accessible, a shareable link must be created. Please set share=True or check your proxy settings to allow access to localhost.
test_async_dict.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ with gr.Blocks() as app:
3
+ state = gr.State()
4
+ b = gr.Button()
5
+ async def fn(s):
6
+ return {"a": 1}
7
+ b.click(fn=fn, inputs=state, outputs=state)
8
+ app.get_api_info()
test_bisect.py ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from app import show_loading, handle_start, process_step
3
+
4
+ with gr.Blocks() as app:
5
+ session_state = gr.State()
6
+ goal_input = gr.Textbox()
7
+ style_radio = gr.Radio(["direct"])
8
+ screen_start = gr.Column()
9
+ screen_task = gr.Column()
10
+ task_display = gr.HTML()
11
+ controls_row = gr.Row()
12
+ start_btn = gr.Button()
13
+
14
+ start_btn.click(
15
+ fn=show_loading,
16
+ outputs=[screen_start, screen_task, task_display, controls_row]
17
+ ).then(
18
+ fn=handle_start,
19
+ inputs=[session_state, goal_input, style_radio],
20
+ outputs=[session_state, task_display, task_display, controls_row]
21
+ )
22
+
23
+ try:
24
+ print(type(app.get_api_info()))
25
+ except Exception as e:
26
+ import traceback
27
+ traceback.print_exc()
test_bisect2.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sys
2
+
3
+ with open("app.py", "r") as f:
4
+ lines = f.readlines()
5
+
6
+ import tempfile
7
+ import subprocess
8
+
9
+ def test_lines(end_line):
10
+ with tempfile.NamedTemporaryFile("w", suffix=".py", delete=False) as f:
11
+ f.writelines(lines[:end_line])
12
+ if "app.launch" not in lines[end_line-1]:
13
+ f.write("\napp.get_api_info()\n")
14
+ name = f.name
15
+
16
+ res = subprocess.run(["python3", name], capture_output=True, text=True)
17
+ return "TypeError: argument of type 'bool' is not iterable" in res.stderr
18
+
19
+ print("Testing...")
20
+ # Binary search
21
+ low = 315
22
+ high = 450
23
+ while low < high:
24
+ mid = (low + high) // 2
25
+ if test_lines(mid):
26
+ high = mid
27
+ else:
28
+ low = mid + 1
29
+
30
+ print(f"First failing line is {low}: {lines[low-1].strip()}")
test_comp.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import app
2
+ from gradio_client import utils
3
+
4
+ for block_id, comp in app.app.blocks.items():
5
+ if hasattr(comp, "api_info"):
6
+ try:
7
+ info = comp.api_info()
8
+ utils.json_schema_to_python_type(info)
9
+ except Exception as e:
10
+ print(f"FAILED ON COMPONENT: {comp.__class__.__name__}")
test_debug.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import app
2
+ import traceback
3
+ try:
4
+ app.app.get_api_info()
5
+ except Exception as e:
6
+ traceback.print_exc()
test_dict.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ with gr.Blocks() as app:
3
+ state = gr.State()
4
+ b = gr.Button()
5
+ def fn(s):
6
+ return {"a": 1}
7
+ b.click(fn=fn, inputs=state, outputs=state)
8
+ app.get_api_info()
test_exact.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ import app
2
+ try:
3
+ app.app.get_api_info()
4
+ print("SUCCESS")
5
+ except Exception as e:
6
+ import traceback
7
+ traceback.print_exc()
test_file_update.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ with gr.Blocks() as app:
3
+ f = gr.File(visible=False)
4
+ b = gr.Button("Test")
5
+ def fn():
6
+ return gr.File(value="test.txt", visible=True)
7
+ b.click(fn=fn, outputs=[f])
8
+ try:
9
+ app.get_api_info()
10
+ print("SUCCESS")
11
+ except Exception as e:
12
+ import traceback
13
+ traceback.print_exc()
test_find_fn.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import app
2
+ import copy
3
+ from gradio_client import utils
4
+
5
+ for idx, fn in enumerate(app.app.fns.values()):
6
+ try:
7
+ info = fn.get_api_info(None)
8
+ client_utils_info = utils.safe_deepcopy(info)
9
+ client_utils.json_schema_to_python_type(client_utils_info)
10
+ except Exception as e:
11
+ print(f"FAILED ON FUNCTION: {fn.name or fn.__class__.__name__} (index {idx})")
test_find_fn2.py ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ import app
2
+ from gradio_client import utils
3
+
4
+ for idx, fn in enumerate(app.app.fns.values()):
5
+ try:
6
+ info = fn.get_api_info(app.app.blocks)
7
+ client_utils_info = utils.safe_deepcopy(info)
8
+ utils.json_schema_to_python_type(client_utils_info)
9
+ except Exception as e:
10
+ print(f"FAILED ON FUNCTION: {fn.name or fn.__class__.__name__} (index {idx})")
test_intercept.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from gradio_client import utils as client_utils
3
+
4
+ original = client_utils.json_schema_to_python_type
5
+
6
+ def hook(schema):
7
+ try:
8
+ return original(schema)
9
+ except Exception as e:
10
+ print("CRASHING SCHEMA:")
11
+ import pprint
12
+ pprint.pprint(schema)
13
+ raise e
14
+
15
+ client_utils.json_schema_to_python_type = hook
16
+
17
+ import app
18
+ app.app.get_api_info()
test_isolate.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ with gr.Blocks() as app:
3
+ state = gr.State({})
4
+ b = gr.Button("Test")
5
+ # b.click(fn=lambda s: s, inputs=state, outputs=state)
6
+ app.get_api_info()
test_isolate2.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ with gr.Blocks() as app:
3
+ state = gr.State({})
4
+ b = gr.Button("Test")
5
+ b.click(fn=lambda s: s, inputs=state, outputs=state)
6
+ app.get_api_info()
test_isolate3.py ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from app import push_to_hub_fn, export_trace_fn, show_loading, show_loading_step, handle_start, handle_done, handle_skip, handle_too_hard
3
+ with gr.Blocks() as app:
4
+ session_state = gr.State({})
5
+ b = gr.Button("Test")
6
+ # Uncomment one by one
7
+ # b.click(fn=export_trace_fn, inputs=[session_state], outputs=[session_state])
8
+ # b.click(fn=push_to_hub_fn, inputs=[session_state], outputs=[session_state])
9
+ app.get_api_info()
test_isolate4.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from app import push_to_hub_fn, export_trace_fn, show_loading, show_loading_step, handle_start, handle_done, handle_skip, handle_too_hard
3
+
4
+ funcs = [export_trace_fn, push_to_hub_fn, show_loading, show_loading_step, handle_start, handle_done, handle_skip, handle_too_hard]
5
+
6
+ for f in funcs:
7
+ with gr.Blocks() as app:
8
+ state = gr.State({})
9
+ b = gr.Button("Test")
10
+ b.click(fn=f, inputs=[state], outputs=[state])
11
+ try:
12
+ app.get_api_info()
13
+ except Exception as e:
14
+ print(f"FAILED on {f.__name__}")
test_isolate5.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ with gr.Blocks() as app:
3
+ col = gr.Column()
4
+ b = gr.Button()
5
+ def fn():
6
+ return gr.update(visible=False)
7
+ b.click(fn=fn, outputs=[col])
8
+ try:
9
+ app.get_api_info()
10
+ except Exception as e:
11
+ print("FAILED on col update")
test_isolate6.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ with gr.Blocks() as app:
3
+ row = gr.Row()
4
+ b = gr.Button()
5
+ def fn():
6
+ return gr.update(visible=False)
7
+ b.click(fn=fn, outputs=[row])
8
+ try:
9
+ app.get_api_info()
10
+ except Exception as e:
11
+ import traceback
12
+ traceback.print_exc()
13
+ print("FAILED on row update")
test_isolate7.py ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ with gr.Blocks() as app:
3
+ f = gr.File(visible=False)
4
+ b = gr.Button()
5
+ def fn():
6
+ return gr.update(visible=True)
7
+ b.click(fn=fn, outputs=[f])
8
+ try:
9
+ app.get_api_info()
10
+ except Exception as e:
11
+ print("FAILED on file")
test_monkeypatch.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio_client.utils as client_utils
2
+ original_get_type = client_utils.get_type
3
+ def safe_get_type(schema):
4
+ if isinstance(schema, bool):
5
+ return "Any"
6
+ return original_get_type(schema)
7
+ client_utils.get_type = safe_get_type
8
+
9
+ import app
10
+ try:
11
+ app.app.get_api_info()
12
+ print("SUCCESS")
13
+ except Exception as e:
14
+ import traceback
15
+ traceback.print_exc()