Spaces:
Sleeping
Sleeping
| import os | |
| import sys | |
| import json | |
| import textwrap | |
| from pathlib import Path | |
| # Detectar ambiente | |
| def is_huggingface(): | |
| return "SPACE_ID" in os.environ or "HF_HOME" in os.environ | |
| RUNNING_IN_HF = is_huggingface() | |
| # ========================== | |
| # MODELOS | |
| # ========================== | |
| LOCAL_MODEL = "qwen3.5:latest" | |
| HF_MODEL = "google/gemma-2-2b-it" | |
| # ========================== | |
| # MODELO LOCAL (OLLAMA) | |
| # ========================== | |
| def call_ollama(prompt): | |
| import requests | |
| try: | |
| resp = requests.post( | |
| "http://localhost:11434/api/generate", | |
| json={"model": LOCAL_MODEL, "prompt": prompt, "stream": False}, | |
| timeout=30 | |
| ) | |
| return resp.json().get("response", "") | |
| except: | |
| return None | |
| # ========================== | |
| # MODELO HUGGING FACE (TRANSFORMERS) | |
| # ========================== | |
| hf_pipeline = None | |
| def load_hf_model(): | |
| global hf_pipeline | |
| if hf_pipeline is None: | |
| from transformers import AutoTokenizer, AutoModelForCausalLM, pipeline | |
| tok = AutoTokenizer.from_pretrained(HF_MODEL) | |
| model = AutoModelForCausalLM.from_pretrained(HF_MODEL) | |
| hf_pipeline = pipeline("text-generation", model=model, tokenizer=tok) | |
| return hf_pipeline | |
| def call_hf_transformers(prompt): | |
| pipe = load_hf_model() | |
| out = pipe(prompt, max_new_tokens=256) | |
| return out[0]["generated_text"] | |
| # ========================== | |
| # FALLBACK | |
| # ========================== | |
| def call_model(prompt): | |
| # 1) Tentar Ollama local | |
| if not RUNNING_IN_HF: | |
| r = call_ollama(prompt) | |
| if r: | |
| return r | |
| # 2) Tentar Gemma local (Transformers) | |
| try: | |
| return call_hf_transformers(prompt) | |
| except: | |
| pass | |
| # 3) Fallback interno | |
| return "Não consegui usar nenhum modelo. Resposta fallback." | |
| # ========================== | |
| # AGENTE | |
| # ========================== | |
| SYSTEM_PROMPT = """ | |
| És um agente de desenvolvimento híbrido. | |
| Cria ficheiros, lê ficheiros e corrige código. | |
| No Hugging Face não usas subprocessos. | |
| Responde sempre em JSON com: | |
| { | |
| "thoughts": "...", | |
| "steps": [ | |
| {"tool": "...", "args": {...}, "comment": "..."} | |
| ] | |
| } | |
| """ | |
| def build_prompt(user): | |
| return SYSTEM_PROMPT + "\nUtilizador:\n" + user + "\nJSON:" | |
| # Ferramentas | |
| def tool_read(path): | |
| p = Path(path) | |
| if not p.exists(): | |
| return "[ERRO] ficheiro não existe" | |
| return p.read_text() | |
| def tool_write(path, content): | |
| p = Path(path) | |
| p.parent.mkdir(parents=True, exist_ok=True) | |
| p.write_text(content) | |
| return "[OK] escrito" | |
| def tool_run(cmd): | |
| if RUNNING_IN_HF: | |
| return "[BLOQUEADO] subprocessos não são permitidos no Hugging Face." | |
| import subprocess | |
| r = subprocess.run(cmd, shell=True, capture_output=True, text=True) | |
| return r.stdout + "\n" + r.stderr | |
| # Execução dos passos | |
| def execute_steps(steps): | |
| outputs = [] | |
| for s in steps: | |
| tool = s.get("tool") | |
| args = s.get("args", {}) | |
| if tool == "read_file": | |
| outputs.append(tool_read(args["path"])) | |
| elif tool == "write_file": | |
| outputs.append(tool_write(args["path"], args["content"])) | |
| elif tool == "run_command": | |
| outputs.append(tool_run(args["command"])) | |
| else: | |
| outputs.append("[ERRO] ferramenta desconhecida") | |
| return "\n".join(outputs) | |
| # ========================== | |
| # INTERFACE GRADIO | |
| # ========================== | |
| import gradio as gr | |
| def agent_chat(user_input): | |
| prompt = build_prompt(user_input) | |
| raw = call_model(prompt) | |
| try: | |
| data = json.loads(raw) | |
| except: | |
| return "Modelo não devolveu JSON válido:\n" + raw | |
| steps = data.get("steps", []) | |
| out = execute_steps(steps) | |
| return out | |
| with gr.Blocks() as demo: | |
| gr.Markdown("# Dev Agent Híbrido (Local + Hugging Face)") | |
| inp = gr.Textbox(label="Comando") | |
| out = gr.Textbox(label="Output") | |
| btn = gr.Button("Executar") | |
| btn.click(agent_chat, inp, out) | |
| demo.launch() | |