Final state before deprecation (replaced by Runner)
This commit is contained in:
parent
19b7b20f02
commit
054690b080
31
agent.py
31
agent.py
@ -18,6 +18,7 @@ from config import (
|
|||||||
AGENT_NAME,
|
AGENT_NAME,
|
||||||
AGENT_SLUG,
|
AGENT_SLUG,
|
||||||
HEARTBEAT_INTERVAL,
|
HEARTBEAT_INTERVAL,
|
||||||
|
LOBBY_CHAT_ID,
|
||||||
)
|
)
|
||||||
from brain import think
|
from brain import think
|
||||||
|
|
||||||
@ -159,6 +160,10 @@ async def connect():
|
|||||||
|
|
||||||
if event == "auth.ok":
|
if event == "auth.ok":
|
||||||
logger.info("Authenticated. Init: %s", json.dumps(msg.get("init", {}), ensure_ascii=False)[:200])
|
logger.info("Authenticated. Init: %s", json.dumps(msg.get("init", {}), ensure_ascii=False)[:200])
|
||||||
|
# Subscribe to lobby chat
|
||||||
|
if LOBBY_CHAT_ID:
|
||||||
|
await send_json(ws, {"event": "chat.subscribe", "chat_id": LOBBY_CHAT_ID})
|
||||||
|
logger.info("Subscribed to lobby chat: %s", LOBBY_CHAT_ID)
|
||||||
|
|
||||||
elif event == "task.assigned":
|
elif event == "task.assigned":
|
||||||
asyncio.create_task(handle_task_assigned(ws, msg))
|
asyncio.create_task(handle_task_assigned(ws, msg))
|
||||||
@ -189,21 +194,29 @@ async def connect():
|
|||||||
def main():
|
def main():
|
||||||
global running
|
global running
|
||||||
|
|
||||||
def stop(*_):
|
|
||||||
global running
|
|
||||||
running = False
|
|
||||||
logger.info("Shutting down...")
|
|
||||||
|
|
||||||
signal.signal(signal.SIGINT, stop)
|
|
||||||
signal.signal(signal.SIGTERM, stop)
|
|
||||||
|
|
||||||
logger.info("🤖 Agent '%s' (%s) starting...", AGENT_NAME, AGENT_SLUG)
|
logger.info("🤖 Agent '%s' (%s) starting...", AGENT_NAME, AGENT_SLUG)
|
||||||
|
|
||||||
if not AGENT_TOKEN:
|
if not AGENT_TOKEN:
|
||||||
logger.error("AGENT_TOKEN is required!")
|
logger.error("AGENT_TOKEN is required!")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
asyncio.run(connect())
|
loop = asyncio.new_event_loop()
|
||||||
|
|
||||||
|
def stop(*_):
|
||||||
|
global running
|
||||||
|
running = False
|
||||||
|
logger.info("Shutting down...")
|
||||||
|
loop.call_soon_threadsafe(loop.stop)
|
||||||
|
|
||||||
|
signal.signal(signal.SIGINT, stop)
|
||||||
|
signal.signal(signal.SIGTERM, stop)
|
||||||
|
|
||||||
|
try:
|
||||||
|
loop.run_until_complete(connect())
|
||||||
|
except RuntimeError:
|
||||||
|
pass # loop stopped by signal
|
||||||
|
finally:
|
||||||
|
loop.close()
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
39
brain.py
39
brain.py
@ -1,4 +1,4 @@
|
|||||||
"""Brain — sends tasks to OpenClaw for execution via sessions_spawn-like webhook."""
|
"""Brain — sends tasks to OpenClaw for AI processing."""
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
import httpx
|
import httpx
|
||||||
@ -9,23 +9,22 @@ logger = logging.getLogger("agent.brain")
|
|||||||
|
|
||||||
|
|
||||||
async def think(task_title: str, task_description: str | None, project_name: str) -> str:
|
async def think(task_title: str, task_description: str | None, project_name: str) -> str:
|
||||||
"""Send a task to OpenClaw and get the result."""
|
"""Send a task to OpenClaw and get the result.
|
||||||
prompt = f"""Ты — агент-кодер в проекте "{project_name}".
|
|
||||||
|
Uses /hooks/wake to inject a system event into the main session
|
||||||
Задача: {task_title}
|
and waits for the response.
|
||||||
"""
|
For now: fire-and-forget via /hooks/agent, returns acknowledgement.
|
||||||
|
"""
|
||||||
|
prompt = f"Ты — агент-кодер в проекте \"{project_name}\".\n\n"
|
||||||
|
prompt += f"Задача: {task_title}\n"
|
||||||
if task_description:
|
if task_description:
|
||||||
prompt += f"\nОписание:\n{task_description}\n"
|
prompt += f"\nОписание:\n{task_description}\n"
|
||||||
|
prompt += "\nВыполни задачу и верни результат кратко и по делу."
|
||||||
|
|
||||||
prompt += """
|
logger.info("Sending to OpenClaw: %s", task_title[:100])
|
||||||
Выполни задачу и верни результат. Если нужно написать код — напиши его.
|
|
||||||
Если нужно проанализировать — проанализируй. Ответь кратко и по делу.
|
|
||||||
"""
|
|
||||||
|
|
||||||
logger.info("Sending task to OpenClaw: %s", task_title)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
async with httpx.AsyncClient(timeout=300) as client:
|
async with httpx.AsyncClient(timeout=120) as client:
|
||||||
resp = await client.post(
|
resp = await client.post(
|
||||||
f"{OPENCLAW_URL}/hooks/agent",
|
f"{OPENCLAW_URL}/hooks/agent",
|
||||||
headers={
|
headers={
|
||||||
@ -33,16 +32,16 @@ async def think(task_title: str, task_description: str | None, project_name: str
|
|||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
},
|
||||||
json={
|
json={
|
||||||
"task": prompt,
|
"message": prompt,
|
||||||
"model": "anthropic/claude-sonnet-4",
|
"label": "agent-coder",
|
||||||
"label": f"agent-coder-task",
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
resp.raise_for_status()
|
resp.raise_for_status()
|
||||||
data = resp.json()
|
data = resp.json()
|
||||||
result = data.get("result", data.get("message", str(data)))
|
run_id = data.get("runId", "unknown")
|
||||||
logger.info("OpenClaw responded: %s chars", len(result))
|
logger.info("OpenClaw run started: %s", run_id)
|
||||||
return result
|
return f"🤖 Задача принята, обрабатываю... (run: {run_id[:8]})"
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("OpenClaw error: %s", e)
|
logger.error("OpenClaw error: %s", e)
|
||||||
return f"Ошибка при выполнении: {e}"
|
return f"❌ Ошибка: {e}"
|
||||||
|
|||||||
@ -16,3 +16,6 @@ AGENT_SLUG = os.getenv("AGENT_SLUG", "coder")
|
|||||||
|
|
||||||
# Heartbeat
|
# Heartbeat
|
||||||
HEARTBEAT_INTERVAL = int(os.getenv("AGENT_HEARTBEAT_INTERVAL", "30"))
|
HEARTBEAT_INTERVAL = int(os.getenv("AGENT_HEARTBEAT_INTERVAL", "30"))
|
||||||
|
|
||||||
|
# Chats to auto-subscribe
|
||||||
|
LOBBY_CHAT_ID = os.getenv("AGENT_LOBBY_CHAT_ID", "25c20eaa-fbf1-4259-8501-0854cc926d0d")
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user