Spaces:
Paused
Paused
Update main.py
Browse files
main.py
CHANGED
|
@@ -104,9 +104,17 @@ DEFAULT_AGENTS = [
|
|
| 104 |
# ── CHAT ROLES — conversational versions for direct chat (not mission mode) ──
|
| 105 |
CHAT_ROLES = {
|
| 106 |
"manager": (
|
| 107 |
-
"Eres el Manager de Mission Control AI,
|
| 108 |
-
"
|
| 109 |
-
"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 110 |
),
|
| 111 |
"backend_dev": (
|
| 112 |
"Eres Backend Dev, un programador senior especializado en Python, APIs, bases de datos y DevOps. "
|
|
@@ -871,13 +879,100 @@ async def chat_with_agent(request: Request):
|
|
| 871 |
try:
|
| 872 |
response = await call_llm_multiturn(agent, history)
|
| 873 |
|
| 874 |
-
#
|
| 875 |
-
img_result
|
| 876 |
-
img_files
|
|
|
|
| 877 |
import json as _json2
|
| 878 |
try:
|
| 879 |
parsed = _json2.loads(response.strip())
|
| 880 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 881 |
queries = parsed.get("queries", [message])[:3]
|
| 882 |
_safe = re.sub(r"[^\w]", "_", message[:28])
|
| 883 |
_ts = datetime.now().strftime("%H%M%S")
|
|
@@ -912,6 +1007,11 @@ async def chat_with_agent(request: Request):
|
|
| 912 |
}
|
| 913 |
if img_result:
|
| 914 |
result.update(img_result)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 915 |
return JSONResponse(result)
|
| 916 |
|
| 917 |
except Exception as e:
|
|
|
|
| 104 |
# ── CHAT ROLES — conversational versions for direct chat (not mission mode) ──
|
| 105 |
CHAT_ROLES = {
|
| 106 |
"manager": (
|
| 107 |
+
"Eres el Manager de Mission Control AI, gerente de proyectos con acceso real a un equipo de agentes IA. "
|
| 108 |
+
"Tu equipo: backend_dev (Python/APIs), frontend_dev (HTML/CSS/JS), analyst (análisis), "
|
| 109 |
+
"writer (redacción), image_agent (imágenes/arte). "
|
| 110 |
+
"REGLA CRÍTICA: Si el usuario pide algo que requiere trabajo real de un agente "
|
| 111 |
+
"(generar imagen, escribir código, hacer Excel, crear informe, diseñar web, etc.), "
|
| 112 |
+
"responde ÚNICAMENTE con este JSON y nada más: "
|
| 113 |
+
'{"action":"delegate","task":"descripcion clara de lo que se necesita"} '
|
| 114 |
+
"Ejemplos que SÍ requieren delegar: "
|
| 115 |
+
"'genera una imagen', 'hazme un script', 'crea un formulario HTML', 'haz un informe', 'excel de ventas'. "
|
| 116 |
+
"Para conversación normal (saludos, preguntas, planificación, consejos) responde con texto normal. "
|
| 117 |
+
"Recuerda el historial y refiérete a él."
|
| 118 |
),
|
| 119 |
"backend_dev": (
|
| 120 |
"Eres Backend Dev, un programador senior especializado en Python, APIs, bases de datos y DevOps. "
|
|
|
|
| 879 |
try:
|
| 880 |
response = await call_llm_multiturn(agent, history)
|
| 881 |
|
| 882 |
+
# Intercept special actions from agents
|
| 883 |
+
img_result = None
|
| 884 |
+
img_files = []
|
| 885 |
+
delegate_result = None
|
| 886 |
import json as _json2
|
| 887 |
try:
|
| 888 |
parsed = _json2.loads(response.strip())
|
| 889 |
+
# Manager delegates to team
|
| 890 |
+
if isinstance(parsed, dict) and parsed.get("action") == "delegate" and agent_key == "manager":
|
| 891 |
+
delegate_task = parsed.get("task", message)
|
| 892 |
+
# Run as a collab mission
|
| 893 |
+
sub_results = {}
|
| 894 |
+
sub_context = "TAREA: " + delegate_task + "\n"
|
| 895 |
+
sub_today = datetime.now().strftime("%A %d de %B de %Y, %H:%M")
|
| 896 |
+
# Detect which agents to use
|
| 897 |
+
lo = delegate_task.lower()
|
| 898 |
+
sub_delegates = []
|
| 899 |
+
if any(w in lo for w in ["imagen","image","foto","dibujo","genera","crea una imagen"]):
|
| 900 |
+
sub_delegates = ["image_agent"]
|
| 901 |
+
elif any(w in lo for w in ["excel","planilla","spreadsheet"]):
|
| 902 |
+
sub_delegates = ["backend_dev"]
|
| 903 |
+
elif any(w in lo for w in ["informe","reporte","documento"]):
|
| 904 |
+
sub_delegates = ["writer","analyst"]
|
| 905 |
+
elif any(w in lo for w in ["html","web","formulario","interfaz"]) and any(w in lo for w in ["api","backend","python"]):
|
| 906 |
+
sub_delegates = ["backend_dev","frontend_dev"]
|
| 907 |
+
elif any(w in lo for w in ["html","web","formulario","interfaz"]):
|
| 908 |
+
sub_delegates = ["frontend_dev"]
|
| 909 |
+
elif any(w in lo for w in ["python","api","script","backend","codigo","código"]):
|
| 910 |
+
sub_delegates = ["backend_dev"]
|
| 911 |
+
else:
|
| 912 |
+
sub_delegates = ["analyst"]
|
| 913 |
+
# Execute each sub-agent
|
| 914 |
+
sub_imgs = []
|
| 915 |
+
for sub_key in sub_delegates:
|
| 916 |
+
if sub_key not in agent_registry: continue
|
| 917 |
+
sub_agent = dict(agent_registry[sub_key])
|
| 918 |
+
sub_role = get_chat_role(sub_key, sub_agent)
|
| 919 |
+
sub_agent["role"] = "HOY ES: " + sub_today + ".\n" + sub_role + "\n\nContexto: " + sub_context
|
| 920 |
+
try:
|
| 921 |
+
if sub_key == "image_agent":
|
| 922 |
+
ip = ("Find images for: " + delegate_task +
|
| 923 |
+
' Respond ONLY: {"image_queries":["t1","t2","t3"]}')
|
| 924 |
+
sub_raw = await call_llm(sub_agent, ip)
|
| 925 |
+
m3 = re.search(r'"image_queries"\s*:\s*\[([^\]]*)\]', sub_raw)
|
| 926 |
+
qs = re.findall(r'"([^"]+)"', m3.group(1)) if m3 else [delegate_task[:40]]
|
| 927 |
+
sub_imgs_r = await asyncio.gather(*[get_image(q, force_generate=True) for q in qs[:3]])
|
| 928 |
+
_safe2 = re.sub(r"[^\w]","_",delegate_task[:28])
|
| 929 |
+
_ts2 = datetime.now().strftime("%H%M%S")
|
| 930 |
+
_base2 = "mgr_" + _safe2 + "_" + _ts2
|
| 931 |
+
for idx2, im2 in enumerate(sub_imgs_r):
|
| 932 |
+
if im2:
|
| 933 |
+
fn2 = _base2 + "_img" + str(idx2+1) + ".jpg"
|
| 934 |
+
(DOCS_DIR / fn2).write_bytes(im2)
|
| 935 |
+
sub_imgs.append(fn2)
|
| 936 |
+
sub_results[sub_key] = {
|
| 937 |
+
"status": "active",
|
| 938 |
+
"message": str(len(sub_imgs)) + " imagen(es) para: " + ", ".join(qs[:3]),
|
| 939 |
+
"img_base": _base2 if sub_imgs else None,
|
| 940 |
+
"img_count": len(sub_imgs),
|
| 941 |
+
}
|
| 942 |
+
sub_context += "\n=== IMAGE AGENT ===\n" + str(len(sub_imgs)) + " images\n"
|
| 943 |
+
else:
|
| 944 |
+
sub_prompt = sub_context + "\nINSTRUCCION: " + delegate_task
|
| 945 |
+
sub_resp = await call_llm_multiturn(sub_agent, [{"role":"user","content":sub_prompt}])
|
| 946 |
+
sub_results[sub_key] = {"status":"active","message":sub_resp,"model":sub_agent["models"][0]}
|
| 947 |
+
sub_context += "\n=== " + sub_key.upper() + " ===\n" + sub_resp[:500] + "\n"
|
| 948 |
+
# Save files
|
| 949 |
+
_ts3 = datetime.now().strftime("%Y%m%d_%H%M%S")
|
| 950 |
+
_safe3 = re.sub(r"[^\w\-]","_",delegate_task[:35])
|
| 951 |
+
if sub_key == "frontend_dev" and not is_skip(sub_resp):
|
| 952 |
+
html3 = re.sub(r"```\w*\n?","",sub_resp); html3 = re.sub(r"```","",html3).strip()
|
| 953 |
+
if len(html3)>80:
|
| 954 |
+
fn3 = _safe3+"_frontend_"+_ts3+".html"
|
| 955 |
+
(DOCS_DIR/fn3).write_text(html3,encoding="utf-8")
|
| 956 |
+
sub_results[sub_key]["doc_file"]=fn3
|
| 957 |
+
elif sub_key == "backend_dev" and not is_skip(sub_resp):
|
| 958 |
+
code3 = re.sub(r"```\w*\n?","",sub_resp); code3 = re.sub(r"```","",code3).strip()
|
| 959 |
+
if len(code3)>80:
|
| 960 |
+
fn3 = _safe3+"_backend_"+_ts3+".py"
|
| 961 |
+
(DOCS_DIR/fn3).write_text(code3,encoding="utf-8")
|
| 962 |
+
sub_results[sub_key]["doc_file"]=fn3
|
| 963 |
+
mission_context_cache[sub_key] = "En tarea reciente: " + delegate_task[:60] + "\n" + sub_resp[:400]
|
| 964 |
+
except Exception as sub_e:
|
| 965 |
+
sub_results[sub_key] = {"status":"resting","message":str(sub_e)}
|
| 966 |
+
# Build manager response text
|
| 967 |
+
parts = ["Delegué la tarea a mi equipo:"]
|
| 968 |
+
for k,r in sub_results.items():
|
| 969 |
+
parts.append("• " + k + ": " + (r.get("message","")[:120] or "done"))
|
| 970 |
+
response = "\n".join(parts)
|
| 971 |
+
delegate_result = {"sub_results": sub_results, "sub_imgs": sub_imgs,
|
| 972 |
+
"img_base": sub_results.get("image_agent",{}).get("img_base"),
|
| 973 |
+
"img_count": sub_results.get("image_agent",{}).get("img_count",0)}
|
| 974 |
+
# ImageAgent: generate image
|
| 975 |
+
elif isinstance(parsed, dict) and parsed.get("action") == "generate_image":
|
| 976 |
queries = parsed.get("queries", [message])[:3]
|
| 977 |
_safe = re.sub(r"[^\w]", "_", message[:28])
|
| 978 |
_ts = datetime.now().strftime("%H%M%S")
|
|
|
|
| 1007 |
}
|
| 1008 |
if img_result:
|
| 1009 |
result.update(img_result)
|
| 1010 |
+
if delegate_result:
|
| 1011 |
+
result["delegate_result"] = delegate_result
|
| 1012 |
+
if delegate_result.get("img_base"):
|
| 1013 |
+
result["img_base"] = delegate_result["img_base"]
|
| 1014 |
+
result["img_count"] = delegate_result["img_count"]
|
| 1015 |
return JSONResponse(result)
|
| 1016 |
|
| 1017 |
except Exception as e:
|