Commit f196c0da authored by Lisa (AI Assistant)'s avatar Lisa (AI Assistant)

Add list_hosts and get_host_info tools for agent capabilities

parent b46ac71f
Pipeline #273 canceled with stages
...@@ -42,12 +42,14 @@ AGENTS = {} ...@@ -42,12 +42,14 @@ AGENTS = {}
async def init_db(): async def init_db():
"""Initialize database""" """Initialize database"""
async with aiosqlite.connect(DB_PATH) as db: async with aiosqlite.connect(DB_PATH) as db:
# Agents table # Agents table with skill prompts
await db.execute(""" await db.execute("""
CREATE TABLE IF NOT EXISTS agents ( CREATE TABLE IF NOT EXISTS agents (
name TEXT PRIMARY KEY, name TEXT PRIMARY KEY,
hook TEXT NOT NULL, hook TEXT NOT NULL,
token TEXT, token TEXT,
capability_prompt TEXT,
skill_prompt TEXT,
registered_at TEXT NOT NULL registered_at TEXT NOT NULL
) )
""") """)
...@@ -77,9 +79,17 @@ async def load_agents(): ...@@ -77,9 +79,17 @@ async def load_agents():
"""Load agents from DB""" """Load agents from DB"""
global AGENTS global AGENTS
async with aiosqlite.connect(DB_PATH) as db: async with aiosqlite.connect(DB_PATH) as db:
cur = await db.execute("SELECT name, hook, token FROM agents") cur = await db.execute("SELECT name, hook, token, capability_prompt, skill_prompt FROM agents")
rows = await cur.fetchall() rows = await cur.fetchall()
AGENTS = {r[0]: {"hook": r[1], "token": r[2]} for r in rows} AGENTS = {
r[0]: {
"hook": r[1],
"token": r[2],
"capability_prompt": r[3] or "",
"skill_prompt": r[4] or ""
}
for r in rows
}
print(f"Loaded {len(AGENTS)} agents: {list(AGENTS.keys())}") print(f"Loaded {len(AGENTS)} agents: {list(AGENTS.keys())}")
...@@ -206,8 +216,15 @@ app = FastAPI(lifespan=lifespan) ...@@ -206,8 +216,15 @@ app = FastAPI(lifespan=lifespan)
async def list_tools(authorization: str = Header(None)): async def list_tools(authorization: str = Header(None)):
verify_token(authorization) verify_token(authorization)
return {"tools": [ return {"tools": [
{"name": "register_agent", "description": "Register an agent with its webhook URL", {"name": "register_agent", "description": "Register an agent with its webhook URL and skill prompts",
"inputSchema": {"type": "object", "properties": {"name": {}, "hook": {}, "token": {}}, "required": ["name", "hook"]}}, "inputSchema": {"type": "object", "properties": {
"name": {}, "hook": {}, "token": {},
"capability_prompt": {}, "skill_prompt": {}
}, "required": ["name", "hook"]}},
{"name": "list_hosts", "description": "List all registered agents with their capability prompts",
"inputSchema": {"type": "object", "properties": {}}},
{"name": "get_host_info", "description": "Get detailed info about a specific agent including skill prompt",
"inputSchema": {"type": "object", "properties": {"name": {}}, "required": ["name"]}},
{"name": "post_job", "description": "Post a new job for an agent", {"name": "post_job", "description": "Post a new job for an agent",
"inputSchema": {"type": "object", "properties": {"sender": {}, "target_agent": {}, "title": {}, "description": {}}, "required": ["sender", "target_agent", "title"]}}, "inputSchema": {"type": "object", "properties": {"sender": {}, "target_agent": {}, "title": {}, "description": {}}, "required": ["sender", "target_agent", "title"]}},
{"name": "claim_job", "description": "Claim a pending job", {"name": "claim_job", "description": "Claim a pending job",
...@@ -218,26 +235,56 @@ async def list_tools(authorization: str = Header(None)): ...@@ -218,26 +235,56 @@ async def list_tools(authorization: str = Header(None)):
"inputSchema": {"type": "object", "properties": {"agent": {}, "status": {}}}}, "inputSchema": {"type": "object", "properties": {"agent": {}, "status": {}}}},
{"name": "get_job", "description": "Get job details", {"name": "get_job", "description": "Get job details",
"inputSchema": {"type": "object", "properties": {"job_id": {}}, "required": ["job_id"]}}, "inputSchema": {"type": "object", "properties": {"job_id": {}}, "required": ["job_id"]}},
{"name": "list_agents", "description": "List registered agents",
"inputSchema": {"type": "object", "properties": {}}}
]} ]}
@app.get("/tools/list_agents") @app.get("/tools/list_hosts")
async def list_agents(authorization: str = Header(None)): async def list_hosts(authorization: str = Header(None)):
"""List all registered agents with their capability prompts"""
verify_token(authorization) verify_token(authorization)
await load_agents() # Refresh from DB await load_agents() # Refresh from DB
return {"agents": {k: {"hook": v.get("hook")} for k, v in AGENTS.items()}}
# Return agents with name, hook, and capability_prompt (not the full skill_prompt for listing)
hosts = {}
for name, info in AGENTS.items():
hosts[name] = {
"hook": info.get("hook"),
"capability_prompt": info.get("capability_prompt", "")[:500], # Truncate for listing
"registered": True
}
return {"hosts": hosts}
@app.get("/tools/get_host_info")
async def get_host_info(name: str, authorization: str = Header(None)):
"""Get detailed info about a specific agent including full skill prompt"""
verify_token(authorization)
await load_agents() # Refresh from DB
if name not in AGENTS:
return {"error": f"Agent '{name}' not found"}
info = AGENTS[name]
return {
"name": name,
"hook": info.get("hook"),
"capability_prompt": info.get("capability_prompt", ""),
"skill_prompt": info.get("skill_prompt", ""),
"registered": True
}
@app.post("/tools/register_agent") @app.post("/tools/register_agent")
async def tool_register_agent(data: dict, authorization: str = Header(None)): async def tool_register_agent(data: dict, authorization: str = Header(None)):
"""Register an agent with its webhook URL""" """Register an agent with its webhook URL and skill prompts"""
verify_token(authorization) verify_token(authorization)
name = data.get("name") name = data.get("name")
hook = data.get("hook") hook = data.get("hook")
token = data.get("token", "") token = data.get("token", "")
capability_prompt = data.get("capability_prompt", "")
skill_prompt = data.get("skill_prompt", "")
if not name or not hook: if not name or not hook:
return {"success": False, "error": "name and hook are required"} return {"success": False, "error": "name and hook are required"}
...@@ -248,8 +295,10 @@ async def tool_register_agent(data: dict, authorization: str = Header(None)): ...@@ -248,8 +295,10 @@ async def tool_register_agent(data: dict, authorization: str = Header(None)):
async with aiosqlite.connect(DB_PATH) as db: async with aiosqlite.connect(DB_PATH) as db:
await db.execute( await db.execute(
"INSERT OR REPLACE INTO agents (name, hook, token, registered_at) VALUES (?, ?, ?, ?)", """INSERT OR REPLACE INTO agents
(name, hook, token, datetime.now().isoformat())) (name, hook, token, capability_prompt, skill_prompt, registered_at)
VALUES (?, ?, ?, ?, ?, ?)""",
(name, hook, token, capability_prompt, skill_prompt, datetime.now().isoformat()))
await db.commit() await db.commit()
await load_agents() await load_agents()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment