Dubberkuro commited on
Commit
08df166
·
verified ·
1 Parent(s): 3b3b1c8

Pro Edition: +restart_space, +check_status, +get_space_logs, +web_search, +example buttons, +better prompts

Browse files
Files changed (1) hide show
  1. app.py +249 -50
app.py CHANGED
@@ -1,8 +1,11 @@
1
  """
2
- AI Coding Agent Crew - Fully Autonomous Edition
3
- ================================================
4
  "video downloader website ဆောက်ပေး" လို့ ပြောလိုက်ရုံနဲ့ အစအဆုံး လုပ်ပေးမယ်
5
  ဘာညွှန်ကြားချက်မှ မပါဘဲ ကိုယ့်ဟာကိုယ် ဆုံးဖြတ်ချက်ချပြီး လုပ်ဆောင်မယ်
 
 
 
6
  """
7
 
8
  import os
@@ -18,7 +21,7 @@ logging.basicConfig(level=logging.INFO)
18
  logger = logging.getLogger(__name__)
19
 
20
  POLLINATIONS_URL = "https://text.pollinations.ai/openai/chat/completions"
21
- MAX_STEPS = 20
22
  HF_TOKEN = os.environ.get("HF_TOKEN", "")
23
 
24
  # ============================================================
@@ -43,6 +46,7 @@ logger.info(f"HF Username: {HF_USERNAME}")
43
  # ============================================================
44
 
45
  def tool_create_space(repo_id: str, sdk: str = "gradio") -> str:
 
46
  from huggingface_hub import HfApi
47
  api = HfApi(token=HF_TOKEN)
48
  try:
@@ -52,6 +56,7 @@ def tool_create_space(repo_id: str, sdk: str = "gradio") -> str:
52
  return f"ERROR: {e}"
53
 
54
  def tool_upload_file(repo_id: str, filename: str, content: str) -> str:
 
55
  from huggingface_hub import HfApi
56
  api = HfApi(token=HF_TOKEN)
57
  try:
@@ -61,7 +66,7 @@ def tool_upload_file(repo_id: str, filename: str, content: str) -> str:
61
  api.upload_file(
62
  path_or_fileobj=tmp, path_in_repo=filename,
63
  repo_id=repo_id, repo_type="space",
64
- commit_message=f"Add {filename}"
65
  )
66
  os.unlink(tmp)
67
  return f"OK: Uploaded {filename} to {repo_id}"
@@ -69,6 +74,7 @@ def tool_upload_file(repo_id: str, filename: str, content: str) -> str:
69
  return f"ERROR: {e}"
70
 
71
  def tool_set_secret(repo_id: str, key: str, value: str) -> str:
 
72
  from huggingface_hub import HfApi
73
  api = HfApi(token=HF_TOKEN)
74
  try:
@@ -78,6 +84,7 @@ def tool_set_secret(repo_id: str, key: str, value: str) -> str:
78
  return f"ERROR: {e}"
79
 
80
  def tool_list_files(repo_id: str) -> str:
 
81
  from huggingface_hub import HfApi
82
  api = HfApi(token=HF_TOKEN)
83
  try:
@@ -87,6 +94,7 @@ def tool_list_files(repo_id: str) -> str:
87
  return f"ERROR: {e}"
88
 
89
  def tool_read_file(repo_id: str, filename: str) -> str:
 
90
  from huggingface_hub import HfApi
91
  api = HfApi(token=HF_TOKEN)
92
  try:
@@ -100,6 +108,7 @@ def tool_read_file(repo_id: str, filename: str) -> str:
100
  return f"ERROR: {e}"
101
 
102
  def tool_delete_file(repo_id: str, filename: str) -> str:
 
103
  from huggingface_hub import HfApi
104
  api = HfApi(token=HF_TOKEN)
105
  try:
@@ -108,6 +117,77 @@ def tool_delete_file(repo_id: str, filename: str) -> str:
108
  except Exception as e:
109
  return f"ERROR: {e}"
110
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
111
  TOOLS = {
112
  "create_space": tool_create_space,
113
  "upload_file": tool_upload_file,
@@ -115,6 +195,10 @@ TOOLS = {
115
  "list_files": tool_list_files,
116
  "read_file": tool_read_file,
117
  "delete_file": tool_delete_file,
 
 
 
 
118
  }
119
 
120
  # ============================================================
@@ -212,11 +296,67 @@ TOOL_DEFS = [
212
  "required": ["repo_id", "filename"]
213
  }
214
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  }
216
  ]
217
 
218
  # ============================================================
219
- # SYSTEM PROMPT
220
  # ============================================================
221
 
222
  SYSTEM_PROMPT = f"""You are a fully autonomous AI coding agent. You make ALL decisions yourself and execute tasks from start to finish WITHOUT asking the user for more instructions.
@@ -229,7 +369,7 @@ When a user asks you to build something, you must:
229
  1. AUTOMATICALLY plan all steps needed
230
  2. Execute each step by calling the appropriate tool
231
  3. After each tool result, decide and execute the next step
232
- 4. Fix errors automatically - never give up
233
  5. Continue until the task is FULLY COMPLETE
234
  6. Give the user the final Space URL
235
 
@@ -238,26 +378,59 @@ When a user asks you to build something, you must:
238
  - NEVER say "please provide..." or "could you tell me..." - JUST DO IT
239
  - ALWAYS upload BOTH app.py AND requirements.txt for any new Space
240
  - Write COMPLETE, WORKING Python code - NO placeholders, NO "...", NO "# your code here"
241
- - Use gradio>=5.0.0 for all web UIs
242
- - After ALL files are uploaded, provide the Space URL
243
  - Reply in the SAME LANGUAGE as the user
244
  - If you get an error, analyze it and FIX it - try a different approach
245
 
246
- ## STEP-BY-STEP for building a web app:
247
  1. create_space(repo_id="{HF_USERNAME}/app-name", sdk="gradio")
248
  2. upload_file(repo_id=..., filename="app.py", content=COMPLETE_CODE)
249
  3. upload_file(repo_id=..., filename="requirements.txt", content="gradio>=5.0.0\\n...")
250
- 4. list_files(repo_id=...) to verify
251
- 5. Provide Space URL: https://huggingface.co/spaces/{{repo_id}}
 
 
252
 
253
- ## CODE GUIDELINES:
254
  - Always: import gradio as gr
255
  - Use gr.Blocks() or gr.Interface()
256
  - Always include demo.launch() at the end
257
  - Handle errors in the code with try/except
258
  - Include proper imports at the top
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
259
 
260
- Remember: You are AUTONOMOUS. Make decisions. Take action. Complete the task."""
 
261
 
262
  # ============================================================
263
  # AI CALLING
@@ -281,23 +454,17 @@ def call_ai(messages, retries=2):
281
  else:
282
  logger.warning(f"AI status {resp.status_code} (attempt {attempt+1})")
283
  if attempt < retries:
284
- import time
285
- time.sleep(3)
286
- continue
287
  return {"content": f"AI API error ({resp.status_code})."}
288
  except req_lib.Timeout:
289
  logger.warning(f"AI timeout (attempt {attempt+1})")
290
  if attempt < retries:
291
- import time
292
- time.sleep(5)
293
- continue
294
  return {"content": "AI request timed out."}
295
  except Exception as e:
296
  logger.error(f"call_ai error: {e}")
297
  if attempt < retries:
298
- import time
299
- time.sleep(3)
300
- continue
301
  return {"content": f"AI error: {e}"}
302
  return {"content": "AI unavailable."}
303
 
@@ -455,7 +622,6 @@ def history_to_messages(history):
455
  continue
456
 
457
  content = item.get("content", "")
458
- # Gradio 6 messages format: content can be a list
459
  if isinstance(content, list):
460
  texts = []
461
  for sub in content:
@@ -469,7 +635,6 @@ def history_to_messages(history):
469
  if not content:
470
  continue
471
 
472
- # Clean progress UI from assistant messages
473
  if role == "assistant":
474
  content = _clean_bot_msg(content)
475
 
@@ -481,10 +646,9 @@ def history_to_messages(history):
481
 
482
  def _clean_bot_msg(text):
483
  """Remove progress UI elements from bot messages for AI context"""
484
- # Remove progress blocks
485
  text = re.sub(r'🚀 လုပ်ဆောင်နေပါပြီ\.\.\.', '', text)
486
  text = re.sub(r'📋 လုပ်ဆောင်ချက်များ:.*?(?=\n\n|\Z)', '', text, flags=re.DOTALL)
487
- text = re.sub(r'⏳ Step \d+/\d+ လုပ်ဆောင်နေဆဲ\.\.\.', '', text)
488
  text = re.sub(r'✅ Step \d+:.*?\n', '', text)
489
  text = re.sub(r'🔄 Step \d+:.*?\n', '', text)
490
  text = re.sub(r'\n{3,}', '\n\n', text)
@@ -495,9 +659,8 @@ def _clean_bot_msg(text):
495
  # ============================================================
496
 
497
  def run_agent(user_message, history):
498
- """Fully autonomous agent - yields (history, response_text) for Gradio"""
499
 
500
- # Build messages for AI
501
  messages = [{"role": "system", "content": SYSTEM_PROMPT}]
502
  messages.extend(history_to_messages(history))
503
  messages.append({"role": "user", "content": user_message})
@@ -512,7 +675,6 @@ def run_agent(user_message, history):
512
 
513
  # 2. No tool call = final response
514
  if not tool_call:
515
- # Check if model is just planning without acting
516
  if text_content and _is_planning_text(text_content):
517
  messages.append({"role": "assistant", "content": text_content})
518
  messages.append({
@@ -524,7 +686,6 @@ def run_agent(user_message, history):
524
  yield progress
525
  continue
526
 
527
- # Final answer
528
  if text_content:
529
  final = _format_final(steps_done, text_content)
530
  else:
@@ -552,24 +713,29 @@ def run_agent(user_message, history):
552
  messages.append({"role": "assistant", "content": f"Calling {tool_name}"})
553
 
554
  if result.startswith("ERROR"):
 
 
 
 
 
 
555
  messages.append({
556
  "role": "user",
557
- "content": f"❌ Tool FAILED: {result}\n\nAnalyze the error and try a different approach. Fix it and retry."
558
  })
559
  else:
560
  done = _check_task_complete(tool_name, result, steps_done)
561
  if done:
562
  messages.append({
563
  "role": "user",
564
- "content": f"✅ Result: {result}\n\nAll files uploaded. Provide the final Space URL and summary. Do NOT call more tools."
565
  })
566
  else:
567
  messages.append({
568
  "role": "user",
569
- "content": f"✅ Result: {result}\n\nContinue with the next step, or if done, provide the Space URL."
570
  })
571
 
572
- # Max steps
573
  yield _format_final(steps_done, "⚠️ အများဆုံး အဆင့်ရောက်ပါပြီ။ ဆက်လုပ်လိုပါက ထပ်မေးပါ။")
574
 
575
 
@@ -589,24 +755,40 @@ def _describe_step(tool_name, tool_args, result):
589
  if tool_name == "create_space":
590
  return f"Space ဆောက်တယ်: {tool_args.get('repo_id', '?')} ({tool_args.get('sdk', 'gradio')})"
591
  elif tool_name == "upload_file":
592
- return f"File တင်တယ်: {tool_args.get('filename', '?')} → {tool_args.get('repo_id', '?')} ({len(tool_args.get('content', ''))} chars)"
593
  elif tool_name == "set_secret":
594
- return f"Secret သတ်မှတ်တယု: {tool_args.get('key', '?')} → {tool_args.get('repo_id', '?')}"
595
  elif tool_name == "list_files":
596
  return f"Files ကြည့်တယု: {tool_args.get('repo_id', '?')}"
597
  elif tool_name == "read_file":
598
  return f"File ဖတ်တယု: {tool_args.get('filename', '?')}"
599
  elif tool_name == "delete_file":
600
  return f"File ဖျက်တယု: {tool_args.get('filename', '?')}"
 
 
 
 
 
 
 
 
601
  return f"{tool_name}"
602
 
603
 
604
  def _check_task_complete(tool_name, result, steps_done):
605
  created = any("Space ဆောက်တယု" in s for s in steps_done)
606
  uploaded_app = any("app.py" in s for s in steps_done)
607
- if tool_name == "list_files" and created and uploaded_app:
 
 
 
 
 
 
 
608
  return True
609
- if tool_name == "upload_file" and "requirements.txt" in result and uploaded_app:
 
610
  return True
611
  return False
612
 
@@ -633,9 +815,18 @@ def _format_final(steps_done, final_text):
633
 
634
 
635
  # ============================================================
636
- # GRADIO UI - Compatible with Gradio 4.x, 5.x, 6.x
637
  # ============================================================
638
 
 
 
 
 
 
 
 
 
 
639
  with gr.Blocks(title="AI Coding Agent Crew") as demo:
640
  gr.Markdown("# 🤖 AI Coding Agent Crew")
641
  gr.Markdown("""**ကိုယ့်ဟာကိုယ် ဆုံးဖြတ်ချက်ချပြီး ကိုယ်ဘာသာ လုပ်ဆောင်နိုင်တဲ့ Agent**
@@ -643,17 +834,30 @@ with gr.Blocks(title="AI Coding Agent Crew") as demo:
643
  လုပ်ဆောင်ချက်တစ်ခု ပြောလိုက်ရုံပါ - Agent က အစအဆုံး ကိုယ့်ဟာကိုယ် လုပ်ပေးမှာ:
644
  • "video downloader website ဆောက်ပေး"
645
  • "image generator app လုပ်ပေး"
646
- • "chatbot website ဆောက်ပေး" """)
 
 
 
647
 
648
  chatbot = gr.Chatbot(height=500)
649
- msg_input = gr.Textbox(
650
- placeholder="ဘာလုပ်ချင်လဲ ရိုက်ထည့်ပါ...",
651
- show_label=False,
652
- scale=4,
653
- )
654
  with gr.Row():
 
 
 
 
 
655
  send_btn = gr.Button("ပို့ရန်", variant="primary", scale=1)
 
 
656
  clear_btn = gr.ClearButton([msg_input, chatbot], scale=1)
 
 
 
 
 
 
 
657
 
658
  def user_submit(user_message, history):
659
  """Add user message to chat (messages format)"""
@@ -667,7 +871,6 @@ with gr.Blocks(title="AI Coding Agent Crew") as demo:
667
  yield history
668
  return
669
 
670
- # Get the last user message text
671
  last_msg = history[-1]
672
  user_message = ""
673
  content = last_msg.get("content", "") if isinstance(last_msg, dict) else ""
@@ -683,17 +886,13 @@ with gr.Blocks(title="AI Coding Agent Crew") as demo:
683
  yield history
684
  return
685
 
686
- # Previous messages (before the last user message)
687
  prev_history = history[:-1]
688
-
689
- # Add placeholder assistant message
690
  history.append({"role": "assistant", "content": "🚀 စတင်လုပ်ဆောင်နေပါပြီ..."})
691
 
692
  for response_text in run_agent(user_message, prev_history):
693
  history[-1] = {"role": "assistant", "content": response_text}
694
  yield history
695
 
696
- # Handle submit
697
  msg_input.submit(
698
  user_submit,
699
  [msg_input, chatbot],
 
1
  """
2
+ AI Coding Agent Crew - Pro Edition
3
+ ===================================
4
  "video downloader website ဆောက်ပေး" လို့ ပြောလိုက်ရုံနဲ့ အစအဆုံး လုပ်ပေးမယ်
5
  ဘာညွှန်ကြားချက်မှ မပါဘဲ ကိုယ့်ဟာကိုယ် ဆုံးဖြတ်ချက်ချပြီး လုပ်ဆောင်မယ်
6
+
7
+ Tools: create_space, upload_file, set_secret, list_files, read_file,
8
+ delete_file, restart_space, check_status, get_space_logs, web_search
9
  """
10
 
11
  import os
 
21
  logger = logging.getLogger(__name__)
22
 
23
  POLLINATIONS_URL = "https://text.pollinations.ai/openai/chat/completions"
24
+ MAX_STEPS = 25
25
  HF_TOKEN = os.environ.get("HF_TOKEN", "")
26
 
27
  # ============================================================
 
46
  # ============================================================
47
 
48
  def tool_create_space(repo_id: str, sdk: str = "gradio") -> str:
49
+ """HF Space အသစ်ဆောက်မယ်"""
50
  from huggingface_hub import HfApi
51
  api = HfApi(token=HF_TOKEN)
52
  try:
 
56
  return f"ERROR: {e}"
57
 
58
  def tool_upload_file(repo_id: str, filename: str, content: str) -> str:
59
+ """HF Space မှာ file upload တင်မယ်"""
60
  from huggingface_hub import HfApi
61
  api = HfApi(token=HF_TOKEN)
62
  try:
 
66
  api.upload_file(
67
  path_or_fileobj=tmp, path_in_repo=filename,
68
  repo_id=repo_id, repo_type="space",
69
+ commit_message=f"Update {filename}"
70
  )
71
  os.unlink(tmp)
72
  return f"OK: Uploaded {filename} to {repo_id}"
 
74
  return f"ERROR: {e}"
75
 
76
  def tool_set_secret(repo_id: str, key: str, value: str) -> str:
77
+ """HF Space မှာ Secret သတ်မှတ်မယ်"""
78
  from huggingface_hub import HfApi
79
  api = HfApi(token=HF_TOKEN)
80
  try:
 
84
  return f"ERROR: {e}"
85
 
86
  def tool_list_files(repo_id: str) -> str:
87
+ """HF Space ရဲ့ files တွေ ကြည့်မယ်"""
88
  from huggingface_hub import HfApi
89
  api = HfApi(token=HF_TOKEN)
90
  try:
 
94
  return f"ERROR: {e}"
95
 
96
  def tool_read_file(repo_id: str, filename: str) -> str:
97
+ """HF Space ကနေ file ဖတ်မယ်"""
98
  from huggingface_hub import HfApi
99
  api = HfApi(token=HF_TOKEN)
100
  try:
 
108
  return f"ERROR: {e}"
109
 
110
  def tool_delete_file(repo_id: str, filename: str) -> str:
111
+ """HF Space ကနေ file ဖျက်မယ်"""
112
  from huggingface_hub import HfApi
113
  api = HfApi(token=HF_TOKEN)
114
  try:
 
117
  except Exception as e:
118
  return f"ERROR: {e}"
119
 
120
+ def tool_restart_space(repo_id: str) -> str:
121
+ """HF Space ကို restart လုပ်မယ် - deploy ပြီးရင် ဒါကို ခေါ်ပါ"""
122
+ from huggingface_hub import HfApi
123
+ api = HfApi(token=HF_TOKEN)
124
+ try:
125
+ api.restart_space(repo_id=repo_id)
126
+ return f"OK: Space '{repo_id}' restarted successfully"
127
+ except Exception as e:
128
+ return f"ERROR: {e}"
129
+
130
+ def tool_check_status(repo_id: str) -> str:
131
+ """HF Space အလုပ်လုပ်နေလား စစ်မယ်"""
132
+ try:
133
+ from huggingface_hub import HfApi
134
+ api = HfApi(token=HF_TOKEN)
135
+ info = api.space_info(repo_id=repo_id)
136
+ stage = info.runtime.stage if info.runtime else "UNKNOWN"
137
+ hardware = info.runtime.hardware if info.runtime else "unknown"
138
+
139
+ # Also try to access the space URL
140
+ space_url = f"https://{repo_id.replace('/', '-')}.hf.space"
141
+ try:
142
+ resp = req_lib.get(space_url, timeout=15)
143
+ http_status = resp.status_code
144
+ except:
145
+ http_status = "unreachable"
146
+
147
+ return f"OK: Stage={stage}, Hardware={hardware}, HTTP={http_status}, URL={space_url}"
148
+ except Exception as e:
149
+ return f"ERROR: {e}"
150
+
151
+ def tool_get_space_logs(repo_id: str) -> str:
152
+ """HF Space ရဲ့ runtime logs ဖတ်မယ် - Error ရှာဖို့ သုံးတယ်"""
153
+ try:
154
+ headers = {"Authorization": f"Bearer {HF_TOKEN}"}
155
+ resp = req_lib.get(
156
+ f"https://huggingface.co/api/spaces/{repo_id}",
157
+ headers=headers, timeout=30
158
+ )
159
+ if resp.status_code == 200:
160
+ data = resp.json()
161
+ runtime = data.get("runtime", {})
162
+ error_msg = runtime.get("errorMessage", None)
163
+ stage = runtime.get("stage", "unknown")
164
+ if error_msg:
165
+ return f"OK: Stage={stage}, Error={error_msg[:2000]}"
166
+ else:
167
+ return f"OK: Stage={stage}, No errors found. Space seems healthy."
168
+ else:
169
+ return f"ERROR: Could not fetch logs (status {resp.status_code})"
170
+ except Exception as e:
171
+ return f"ERROR: {e}"
172
+
173
+ def tool_web_search(query: str) -> str:
174
+ """ဝဘ်မှာ ရှာမယ် - API examples, code snippets, documentation ရှာဖို့"""
175
+ try:
176
+ resp = req_lib.get(
177
+ f"https://text.pollinations.ai/",
178
+ params={"prompt": f"Search results for: {query}. Provide relevant URLs, code examples, and documentation links.", "model": "openai"},
179
+ timeout=30
180
+ )
181
+ if resp.status_code == 200:
182
+ text = resp.text[:3000]
183
+ return f"OK: Search results for '{query}':\n{text}"
184
+ else:
185
+ return f"ERROR: Search failed (status {resp.status_code})"
186
+ except Exception as e:
187
+ return f"ERROR: {e}"
188
+
189
+
190
+ # Tool Registry
191
  TOOLS = {
192
  "create_space": tool_create_space,
193
  "upload_file": tool_upload_file,
 
195
  "list_files": tool_list_files,
196
  "read_file": tool_read_file,
197
  "delete_file": tool_delete_file,
198
+ "restart_space": tool_restart_space,
199
+ "check_status": tool_check_status,
200
+ "get_space_logs": tool_get_space_logs,
201
+ "web_search": tool_web_search,
202
  }
203
 
204
  # ============================================================
 
296
  "required": ["repo_id", "filename"]
297
  }
298
  }
299
+ },
300
+ {
301
+ "type": "function",
302
+ "function": {
303
+ "name": "restart_space",
304
+ "description": "Restart a Space after deploying files. Call this AFTER uploading all files.",
305
+ "parameters": {
306
+ "type": "object",
307
+ "properties": {
308
+ "repo_id": {"type": "string", "description": "Space ID to restart"}
309
+ },
310
+ "required": ["repo_id"]
311
+ }
312
+ }
313
+ },
314
+ {
315
+ "type": "function",
316
+ "function": {
317
+ "name": "check_status",
318
+ "description": "Check if a Space is running, its stage, and HTTP status",
319
+ "parameters": {
320
+ "type": "object",
321
+ "properties": {
322
+ "repo_id": {"type": "string", "description": "Space ID"}
323
+ },
324
+ "required": ["repo_id"]
325
+ }
326
+ }
327
+ },
328
+ {
329
+ "type": "function",
330
+ "function": {
331
+ "name": "get_space_logs",
332
+ "description": "Get runtime error logs from a Space. Use this when a Space has RUNTIME_ERROR to diagnose issues.",
333
+ "parameters": {
334
+ "type": "object",
335
+ "properties": {
336
+ "repo_id": {"type": "string", "description": "Space ID"}
337
+ },
338
+ "required": ["repo_id"]
339
+ }
340
+ }
341
+ },
342
+ {
343
+ "type": "function",
344
+ "function": {
345
+ "name": "web_search",
346
+ "description": "Search the web for API documentation, code examples, or how-to guides. Use when you need info about a library or API.",
347
+ "parameters": {
348
+ "type": "object",
349
+ "properties": {
350
+ "query": {"type": "string", "description": "Search query"}
351
+ },
352
+ "required": ["query"]
353
+ }
354
+ }
355
  }
356
  ]
357
 
358
  # ============================================================
359
+ # SYSTEM PROMPT - Agent ရဲ့ ဦးနှောက်
360
  # ============================================================
361
 
362
  SYSTEM_PROMPT = f"""You are a fully autonomous AI coding agent. You make ALL decisions yourself and execute tasks from start to finish WITHOUT asking the user for more instructions.
 
369
  1. AUTOMATICALLY plan all steps needed
370
  2. Execute each step by calling the appropriate tool
371
  3. After each tool result, decide and execute the next step
372
+ 4. Fix errors automatically by reading logs and retrying
373
  5. Continue until the task is FULLY COMPLETE
374
  6. Give the user the final Space URL
375
 
 
378
  - NEVER say "please provide..." or "could you tell me..." - JUST DO IT
379
  - ALWAYS upload BOTH app.py AND requirements.txt for any new Space
380
  - Write COMPLETE, WORKING Python code - NO placeholders, NO "...", NO "# your code here"
381
+ - After ALL files are uploaded, restart the Space and check status
382
+ - If Space has RUNTIME_ERROR, read logs with get_space_logs, fix the code, re-upload
383
  - Reply in the SAME LANGUAGE as the user
384
  - If you get an error, analyze it and FIX it - try a different approach
385
 
386
+ ## DEPLOYMENT WORKFLOW:
387
  1. create_space(repo_id="{HF_USERNAME}/app-name", sdk="gradio")
388
  2. upload_file(repo_id=..., filename="app.py", content=COMPLETE_CODE)
389
  3. upload_file(repo_id=..., filename="requirements.txt", content="gradio>=5.0.0\\n...")
390
+ 4. restart_space(repo_id=...) to activate
391
+ 5. check_status(repo_id=...) to verify
392
+ 6. If error: get_space_logs(repo_id=...) → read error → fix code → re-upload → restart
393
+ 7. Provide Space URL: https://huggingface.co/spaces/{{repo_id}}
394
 
395
+ ## IMPORTANT CODE GUIDELINES:
396
  - Always: import gradio as gr
397
  - Use gr.Blocks() or gr.Interface()
398
  - Always include demo.launch() at the end
399
  - Handle errors in the code with try/except
400
  - Include proper imports at the top
401
+ - For Gradio 6.x: do NOT use type="messages" in Chatbot, do NOT pass css to Blocks (pass to launch)
402
+ - For Gradio 6.x: Chatbot uses messages format by default (list of dicts with role/content)
403
+ - Use gr.ChatInterface for simple chat apps
404
+
405
+ ## CODE TEMPLATES:
406
+
407
+ Simple Chat App:
408
+ ```python
409
+ import gradio as gr
410
+
411
+ def chat(message, history):
412
+ return f"Echo: {{message}}"
413
+
414
+ demo = gr.ChatInterface(fn=chat, title="My Chat App")
415
+ demo.launch()
416
+ ```
417
+
418
+ Blocks App with UI:
419
+ ```python
420
+ import gradio as gr
421
+
422
+ with gr.Blocks(title="My App") as demo:
423
+ gr.Markdown("# My App")
424
+ input_text = gr.Textbox(label="Input")
425
+ output_text = gr.Textbox(label="Output")
426
+ btn = gr.Button("Submit")
427
+ btn.click(fn=lambda x: x.upper(), inputs=input_text, outputs=output_text)
428
+
429
+ demo.launch()
430
+ ```
431
 
432
+ Remember: You are AUTONOMOUS. Make decisions. Take action. Complete the task.
433
+ After deploying, ALWAYS restart the Space and verify it works. If it fails, read logs and fix it."""
434
 
435
  # ============================================================
436
  # AI CALLING
 
454
  else:
455
  logger.warning(f"AI status {resp.status_code} (attempt {attempt+1})")
456
  if attempt < retries:
457
+ import time; time.sleep(3); continue
 
 
458
  return {"content": f"AI API error ({resp.status_code})."}
459
  except req_lib.Timeout:
460
  logger.warning(f"AI timeout (attempt {attempt+1})")
461
  if attempt < retries:
462
+ import time; time.sleep(5); continue
 
 
463
  return {"content": "AI request timed out."}
464
  except Exception as e:
465
  logger.error(f"call_ai error: {e}")
466
  if attempt < retries:
467
+ import time; time.sleep(3); continue
 
 
468
  return {"content": f"AI error: {e}"}
469
  return {"content": "AI unavailable."}
470
 
 
622
  continue
623
 
624
  content = item.get("content", "")
 
625
  if isinstance(content, list):
626
  texts = []
627
  for sub in content:
 
635
  if not content:
636
  continue
637
 
 
638
  if role == "assistant":
639
  content = _clean_bot_msg(content)
640
 
 
646
 
647
  def _clean_bot_msg(text):
648
  """Remove progress UI elements from bot messages for AI context"""
 
649
  text = re.sub(r'🚀 လုပ်ဆောင်နေပါပြီ\.\.\.', '', text)
650
  text = re.sub(r'📋 လုပ်ဆောင်ချက်များ:.*?(?=\n\n|\Z)', '', text, flags=re.DOTALL)
651
+ text = re.sub(r'⏳ Step \d+/\d+.*?\n', '', text)
652
  text = re.sub(r'✅ Step \d+:.*?\n', '', text)
653
  text = re.sub(r'🔄 Step \d+:.*?\n', '', text)
654
  text = re.sub(r'\n{3,}', '\n\n', text)
 
659
  # ============================================================
660
 
661
  def run_agent(user_message, history):
662
+ """Fully autonomous agent - yields response_text for Gradio"""
663
 
 
664
  messages = [{"role": "system", "content": SYSTEM_PROMPT}]
665
  messages.extend(history_to_messages(history))
666
  messages.append({"role": "user", "content": user_message})
 
675
 
676
  # 2. No tool call = final response
677
  if not tool_call:
 
678
  if text_content and _is_planning_text(text_content):
679
  messages.append({"role": "assistant", "content": text_content})
680
  messages.append({
 
686
  yield progress
687
  continue
688
 
 
689
  if text_content:
690
  final = _format_final(steps_done, text_content)
691
  else:
 
713
  messages.append({"role": "assistant", "content": f"Calling {tool_name}"})
714
 
715
  if result.startswith("ERROR"):
716
+ # If it's a Space error, suggest reading logs
717
+ extra = ""
718
+ if "space" in tool_name.lower() or "upload" in tool_name.lower():
719
+ repo_id = tool_args.get("repo_id", "")
720
+ if repo_id:
721
+ extra = f"\n\nTry: get_space_logs(repo_id='{repo_id}') to see the error details."
722
  messages.append({
723
  "role": "user",
724
+ "content": f"❌ Tool FAILED: {result}{extra}\n\nAnalyze the error and try a different approach. Fix it and retry."
725
  })
726
  else:
727
  done = _check_task_complete(tool_name, result, steps_done)
728
  if done:
729
  messages.append({
730
  "role": "user",
731
+ "content": f"✅ Result: {result}\n\nAll files uploaded and Space restarted. Provide the final Space URL and summary to the user. Do NOT call more tools."
732
  })
733
  else:
734
  messages.append({
735
  "role": "user",
736
+ "content": f"✅ Result: {result}\n\nContinue with the next step. If all files are uploaded, restart the Space and check status."
737
  })
738
 
 
739
  yield _format_final(steps_done, "⚠️ အများဆုံး အဆင့်ရောက်ပါပြီ။ ဆက်လုပ်လိုပါက ထပ်မေးပါ။")
740
 
741
 
 
755
  if tool_name == "create_space":
756
  return f"Space ဆောက်တယ်: {tool_args.get('repo_id', '?')} ({tool_args.get('sdk', 'gradio')})"
757
  elif tool_name == "upload_file":
758
+ return f"File တင်တယ်: {tool_args.get('filename', '?')} ({len(tool_args.get('content', ''))} chars)"
759
  elif tool_name == "set_secret":
760
+ return f"Secret သတ်မှတ်တယု: {tool_args.get('key', '?')}"
761
  elif tool_name == "list_files":
762
  return f"Files ကြည့်တယု: {tool_args.get('repo_id', '?')}"
763
  elif tool_name == "read_file":
764
  return f"File ဖတ်တယု: {tool_args.get('filename', '?')}"
765
  elif tool_name == "delete_file":
766
  return f"File ဖျက်တယု: {tool_args.get('filename', '?')}"
767
+ elif tool_name == "restart_space":
768
+ return f"Space restart လုပ်တယု: {tool_args.get('repo_id', '?')}"
769
+ elif tool_name == "check_status":
770
+ return f"Status စစ်တယု: {tool_args.get('repo_id', '?')}"
771
+ elif tool_name == "get_space_logs":
772
+ return f"Logs ဖတ်တယု: {tool_args.get('repo_id', '?')}"
773
+ elif tool_name == "web_search":
774
+ return f"Web ရှာတယု: {tool_args.get('query', '?')[:50]}"
775
  return f"{tool_name}"
776
 
777
 
778
  def _check_task_complete(tool_name, result, steps_done):
779
  created = any("Space ဆောက်တယု" in s for s in steps_done)
780
  uploaded_app = any("app.py" in s for s in steps_done)
781
+ restarted = any("restart" in s.lower() for s in steps_done)
782
+ checked = any("Status စစ်တယု" in s or "Logs ဖတ်တယု" in s for s in steps_done)
783
+
784
+ # If we've restarted and checked, we're done
785
+ if tool_name == "check_status" and restarted and uploaded_app:
786
+ return True
787
+ # If we've read logs after a restart, also done
788
+ if tool_name == "get_space_logs" and restarted and uploaded_app:
789
  return True
790
+ # If we restarted after uploading both files
791
+ if tool_name == "restart_space" and created and uploaded_app:
792
  return True
793
  return False
794
 
 
815
 
816
 
817
  # ============================================================
818
+ # GRADIO UI
819
  # ============================================================
820
 
821
+ EXAMPLES = [
822
+ "video downloader website ဆောက်ပေး",
823
+ "image generator app လုပ်ပေး",
824
+ "chatbot website ဆောက်ပေး",
825
+ "text to speech app လုပ်ပေး",
826
+ "PDF summarizer app ဆောက်ပေး",
827
+ "မင်းရဲ့ Space တွေ ဘာတွေရှိလဲ",
828
+ ]
829
+
830
  with gr.Blocks(title="AI Coding Agent Crew") as demo:
831
  gr.Markdown("# 🤖 AI Coding Agent Crew")
832
  gr.Markdown("""**ကိုယ့်ဟာကိုယ် ဆုံးဖြတ်ချက်ချပြီး ကိုယ်ဘာသာ လုပ်ဆောင်နိုင်တဲ့ Agent**
 
834
  လုပ်ဆောင်ချက်တစ်ခု ပြောလိုက်ရုံပါ - Agent က အစအဆုံး ကိုယ့်ဟာကိုယ် လုပ်ပေးမှာ:
835
  • "video downloader website ဆောက်ပေး"
836
  • "image generator app လုပ်ပေး"
837
+ • "chatbot website ဆောက်ပေး"
838
+ • "PDF summarizer app ဆောက်ပေး"
839
+
840
+ 🔧 **Tools**: Space ဆောက်, File တင်, Secret သတ်မှတ်, Restart, Status စစ်, Logs ဖတ်, Web ရှာ""")
841
 
842
  chatbot = gr.Chatbot(height=500)
843
+
 
 
 
 
844
  with gr.Row():
845
+ msg_input = gr.Textbox(
846
+ placeholder="ဘာလုပ်ချင်လဲ ရိုက်ထည့်ပါ...",
847
+ show_label=False,
848
+ scale=4,
849
+ )
850
  send_btn = gr.Button("ပို့ရန်", variant="primary", scale=1)
851
+
852
+ with gr.Row():
853
  clear_btn = gr.ClearButton([msg_input, chatbot], scale=1)
854
+
855
+ # Example buttons
856
+ gr.Examples(
857
+ examples=EXAMPLES,
858
+ inputs=msg_input,
859
+ label="နမူနာ ခလုတ်တွေ (နှိပ်လိုက်ရုံပါ)"
860
+ )
861
 
862
  def user_submit(user_message, history):
863
  """Add user message to chat (messages format)"""
 
871
  yield history
872
  return
873
 
 
874
  last_msg = history[-1]
875
  user_message = ""
876
  content = last_msg.get("content", "") if isinstance(last_msg, dict) else ""
 
886
  yield history
887
  return
888
 
 
889
  prev_history = history[:-1]
 
 
890
  history.append({"role": "assistant", "content": "🚀 စတင်လုပ်ဆောင်နေပါပြီ..."})
891
 
892
  for response_text in run_agent(user_message, prev_history):
893
  history[-1] = {"role": "assistant", "content": response_text}
894
  yield history
895
 
 
896
  msg_input.submit(
897
  user_submit,
898
  [msg_input, chatbot],