Spaces:
Paused
Paused
| import os, json, tempfile, pathlib, zipfile, io, spaces, time | |
| spaces.GPU(lambda: None)() | |
| import gradio as gr | |
| from huggingface_hub import InferenceClient | |
| MODEL = os.environ.get("SKILLS_MODEL", "meta-llama/Llama-3.1-8B-Instruct") | |
| TOKEN = os.environ.get("OPENAI_API_KEY", "") | |
| SYS = ( | |
| "You are SkillBot, helping users create Codex skills. Follow this process:\n" | |
| "1. Understand: Ask what the skill does, get 2-3 concrete scenarios\n" | |
| "2. Name: Suggest a hyphen-case name and confirm\n" | |
| "3. Generate: When ready, output ONLY a JSON object on one line with these fields:\n" | |
| ' {"skill_name":"...","display_name":"...","description":"...","short_description":"...","default_prompt":"...","skill_body":"markdown body"}\n' | |
| "Rules: Ask 1-2 questions at a time. For skill_body write real markdown with Overview, Quick Start, Workflow. Speak Chinese if user speaks Chinese." | |
| ) | |
| def chat(message, history): | |
| msgs = [{"role": "system", "content": SYS}] | |
| for m in (history or []): | |
| if isinstance(m, dict): | |
| msgs.append(m) | |
| elif isinstance(m, (list, tuple)): | |
| msgs.append({"role": "user", "content": m[0]}) | |
| if m[1]: msgs.append({"role": "assistant", "content": m[1]}) | |
| msgs.append({"role": "user", "content": message}) | |
| client = InferenceClient(model=MODEL, token=TOKEN) | |
| resp = client.chat_completion(messages=msgs, max_tokens=2048, temperature=0.7) | |
| reply = resp.choices[0].message.content | |
| # Check if model output contains skill JSON | |
| skill_data = None | |
| import re | |
| for match in re.finditer(r"\{", reply): | |
| start = match.start() | |
| depth, end = 0, len(reply) | |
| for i in range(start, len(reply)): | |
| if reply[i] == "{": depth += 1 | |
| elif reply[i] == "}": | |
| depth -= 1 | |
| if depth == 0: end = i + 1; break | |
| candidate = reply[start:end] | |
| try: | |
| data = json.loads(candidate) | |
| if "skill_name" in data and "skill_body" in data: | |
| skill_data = data | |
| reply = reply[:start].strip() + "\n\nSkill generated! Click download below." | |
| break | |
| except: pass | |
| # Save skill if generated | |
| zip_path = None | |
| if skill_data: | |
| sd = skill_data | |
| # Build skill files in temp dir | |
| tmp = tempfile.mkdtemp() | |
| skill_dir = pathlib.Path(tmp) / sd["skill_name"] | |
| skill_dir.mkdir() | |
| agents = skill_dir / "agents"; agents.mkdir() | |
| md = f'---\nname: {sd["skill_name"]}\ndescription: "{sd.get("description","")}"\n---\n{sd["skill_body"]}' | |
| (skill_dir / "SKILL.md").write_text(md, encoding="utf-8") | |
| yaml = f'display_name: "{sd.get("display_name",sd["skill_name"])}"\nshort_description: "{sd.get("short_description","")}"\ndefault_prompt: "{sd.get("default_prompt","")}"' | |
| (agents / "openai.yaml").write_text(yaml, encoding="utf-8") | |
| # Create zip | |
| buf = io.BytesIO() | |
| with zipfile.ZipFile(buf, "w") as zf: | |
| zf.writestr(f'{sd["skill_name"]}/SKILL.md', md) | |
| zf.writestr(f'{sd["skill_name"]}/agents/openai.yaml', yaml) | |
| zip_path = f"/tmp/{sd['skill_name']}.zip" | |
| with open(zip_path, "wb") as f: f.write(buf.getvalue()) | |
| history.append({"role": "user", "content": message}) | |
| history.append({"role": "assistant", "content": reply}) | |
| if zip_path: | |
| return history, gr.File(value=zip_path, visible=True) | |
| return history, gr.File(visible=False) | |
| with gr.Blocks(title="SkillBot", theme=gr.themes.Soft()) as demo: | |
| gr.Markdown("# SkillBot - Create a Codex Skill by Chatting") | |
| chatbot = gr.Chatbot(label="Conversation", height=400) | |
| msg = gr.Textbox(placeholder="Describe what skill you want to create...", label="Message") | |
| with gr.Row(): | |
| send = gr.Button("Send", variant="primary") | |
| clear_btn = gr.Button("New Skill") | |
| file_out = gr.File(label="Download Skill", visible=False) | |
| send.click(chat, [msg, chatbot], [chatbot, file_out]).then(lambda: "", None, [msg]) | |
| msg.submit(chat, [msg, chatbot], [chatbot, file_out]).then(lambda: "", None, [msg]) | |
| clear_btn.click(lambda: ([], gr.File(visible=False)), None, [chatbot, file_out]) | |
| demo.launch(server_name="0.0.0.0", server_port=int(os.environ.get("PORT", 7860))) | |
| # v1785312598.4308667 | |