Fixed auto approver

This commit is contained in:
Niels Geens
2024-11-22 17:11:06 +01:00
parent 8766a945c0
commit 69f4f8a6fc
8 changed files with 343 additions and 244 deletions

View File

@@ -2,15 +2,16 @@ from aiohttp import web
import json
import asyncio
from ..auto_approver import AutoApprover
from ..web_agent import WebAgent
from ..web_io_buffer import WebIOBuffer
from .util import wrap_async
class Api:
def __init__(self, app: web.Application, agent: WebAgent, io_buffer: WebIOBuffer):
def __init__(self, app: web.Application, agent: WebAgent, io_buffer: WebIOBuffer, auto_approver: AutoApprover):
self._app = app
self._agent = agent
self._io_buffer = io_buffer
self._auto_approver = auto_approver
self._init_routes()
@@ -23,10 +24,13 @@ class Api:
self._app.router.add_post("/api/clear", self._clear_output)
self._app.router.add_get("/api/output/{llm}", self._get_output)
self._app.router.add_get("/api/llms", self._get_llms)
@property
def app(self):
return self._app
self._app.router.add_get("/api/auto_approver/config", self._get_auto_approver_config)
self._app.router.add_post("/api/auto_approver/config", self._set_auto_approver_config)
self._app.router.add_post("/api/auto_approver/context_enabled", self._set_context_enabled)
self._app.router.add_post("/api/auto_approver/response_enabled", self._set_response_enabled)
self._app.router.add_post("/api/auto_approver/context_timeout", self._set_context_timeout)
self._app.router.add_post("/api/auto_approver/response_timeout", self._set_response_timeout)
self._app.router.add_post("/api/auto_approver/llm", self._set_llm_name)
async def _run_inference(self, request: web.Request) -> web.Response:
"""Start inference on specified LLM."""
@@ -95,3 +99,79 @@ class Api:
}),
content_type="application/json"
)
async def _get_auto_approver_config(self, request: web.Request) -> web.Response:
"""Get current auto approver configuration."""
return web.Response(
text=json.dumps(self._auto_approver.config),
content_type="application/json"
)
async def _set_auto_approver_config(self, request: web.Request) -> web.Response:
"""Update auto approver configuration."""
data = await request.json()
try:
self._auto_approver.set_config(data)
return web.Response(status=200)
except (ValueError, KeyError) as e:
return web.Response(status=400, text=str(e))
async def _set_context_enabled(self, request: web.Request) -> web.Response:
"""Set context auto-approval enabled state."""
data = await request.json()
enabled = data.get("enabled")
if enabled is None:
return web.Response(status=400, text="Missing enabled parameter")
try:
self._auto_approver.context_enabled = enabled
return web.Response(status=200)
except ValueError as e:
return web.Response(status=400, text=str(e))
async def _set_response_enabled(self, request: web.Request) -> web.Response:
"""Set response auto-approval enabled state."""
data = await request.json()
enabled = data.get("enabled")
if enabled is None:
return web.Response(status=400, text="Missing enabled parameter")
try:
self._auto_approver.response_enabled = enabled
return web.Response(status=200)
except ValueError as e:
return web.Response(status=400, text=str(e))
async def _set_context_timeout(self, request: web.Request) -> web.Response:
"""Set context auto-approval timeout."""
data = await request.json()
timeout = data.get("timeout")
if timeout is None:
return web.Response(status=400, text="Missing timeout parameter")
try:
self._auto_approver.context_timeout = float(timeout)
return web.Response(status=200)
except ValueError as e:
return web.Response(status=400, text=str(e))
async def _set_response_timeout(self, request: web.Request) -> web.Response:
"""Set response auto-approval timeout."""
data = await request.json()
timeout = data.get("timeout")
if timeout is None:
return web.Response(status=400, text="Missing timeout parameter")
try:
self._auto_approver.response_timeout = float(timeout)
return web.Response(status=200)
except ValueError as e:
return web.Response(status=400, text=str(e))
async def _set_llm_name(self, request: web.Request) -> web.Response:
"""Set LLM name for auto-approval."""
data = await request.json()
name = data.get("name")
if name is None:
return web.Response(status=400, text="Missing name parameter")
try:
self._auto_approver.llm_name = name
return web.Response(status=200)
except ValueError as e:
return web.Response(status=400, text=str(e))

View File

@@ -0,0 +1,53 @@
from aiohttp import web, WSMsgType
from typing import Dict, Set
from ..auto_approver import AutoApprover, AutoApproverConfig
from .util import wrap_async
class AutoApproverWebSocket:
"""
WebSocket handler for AutoApprover configuration.
Broadcasts config updates to all connected clients.
"""
def __init__(self, auto_approver: AutoApprover):
self._auto_approver = auto_approver
self._clients: Set[web.WebSocketResponse] = set()
self._auto_approver.add_config_change_handler(wrap_async(self._handle_config_change))
async def _broadcast_message(self, message: Dict):
"""Broadcast message to all connected clients."""
disconnected = set()
for ws in self._clients:
try:
await ws.send_json(message)
except ConnectionResetError:
disconnected.add(ws)
self._clients -= disconnected
async def _handle_config_change(self, config: AutoApproverConfig):
"""Handle config changes from the AutoApprover."""
await self._broadcast_message({
"config": config
})
async def handle_connection(self, request: web.Request) -> web.WebSocketResponse:
"""Handle new WebSocket connections."""
ws = web.WebSocketResponse(heartbeat=30)
await ws.prepare(request)
self._clients.add(ws)
try:
# Send initial config
await ws.send_json({
"config": self._auto_approver.config
})
async for msg in ws:
if msg.type == WSMsgType.ERROR:
print(f"WebSocket connection closed with error: {ws.exception()}")
finally:
self._clients.remove(ws)
return ws

View File

@@ -2,19 +2,23 @@ from aiohttp import web
from ..web_agent import WebAgent
from ..web_io_buffer import WebIOBuffer
from ..auto_approver import AutoApprover
from .llm_websocket import LlmWebSocket
from .context_websocket import ContextWebSocket
from .token_websocket import TokenWebSocket
from .stdout_websocket import StdoutWebSocket
from .auto_approver_websocket import AutoApproverWebSocket
class Websockets:
def __init__(self, app: web.Application, agent: WebAgent, io_buffer: WebIOBuffer):
def __init__(self, app: web.Application, agent: WebAgent, io_buffer: WebIOBuffer, auto_approver: AutoApprover):
self._llm_ws = LlmWebSocket(agent)
self._context_ws = ContextWebSocket(agent)
self._token_ws = TokenWebSocket(agent)
self._stdout_ws = StdoutWebSocket(io_buffer)
self._auto_approver_ws = AutoApproverWebSocket(auto_approver)
app.router.add_get("/ws/llm", self._llm_ws.handle_connection)
app.router.add_get("/ws/context", self._context_ws.handle_connection)
app.router.add_get("/ws/token", self._token_ws.handle_connection)
app.router.add_get("/ws/stdout", self._stdout_ws.handle_connection)
app.router.add_get("/ws/stdout", self._stdout_ws.handle_connection)
app.router.add_get("/ws/auto_approver", self._auto_approver_ws.handle_connection)