brain / src /services /brain_backup /middleware.py
Leon4gr45's picture
Deploy complete BrainAPI source ea2acb63d782
89e57b7 verified
Raw History Blame Contribute Delete
2.83 kB
"""Admission leases for HTTP and MCP content mutations (reads stay available)."""
import json
from starlette.responses import JSONResponse
from src.services.auth import request_permission
from .maintenance import admission
from .git import BackupError
READ_TOOLS = {'memory_search', 'memory_context', 'memory_neighbors', 'memory_entity',
'memory_task_status', 'search_memory', 'traverse_graph', 'get_brains',
'get_entity_info', 'get_instructions'}
READ_TOOLS.update({'list_brains', 'search_semantically', 'get_search_operation_instructions'})
class ContentAdmissionMiddleware:
def __init__(self, app):
self.app = app
async def __call__(self, scope, receive, send):
if scope['type'] != 'http':
return await self.app(scope, receive, send)
path, method = scope.get('path', ''), scope.get('method', 'GET')
write = request_permission(method, path) == 'memory:write'
if path.startswith(('/auth/', '/system/backup/', '/system/access-tokens')):
write = False
if '/mcp' in path and method == 'POST':
chunks = []
while True:
msg = await receive()
if msg['type'] != 'http.request':
return
chunks.append(msg.get('body', b''))
if sum(map(len, chunks)) > 2 * 1024 * 1024:
return await JSONResponse({'error': {'code': 'INVALID_REQUEST'}}, status_code=413)(scope, receive, send)
if not msg.get('more_body', False):
break
body = b''.join(chunks)
try:
payload = json.loads(body)
calls = payload if isinstance(payload, list) else [payload]
write = any(isinstance(c, dict) and c.get('method') == 'tools/call'
and (c.get('params') or {}).get('name') not in READ_TOOLS for c in calls)
except (ValueError, TypeError, AttributeError):
write = True
previous_receive = receive
delivered = False
async def replay():
nonlocal delivered
if not delivered:
delivered = True
return {'type': 'http.request', 'body': body, 'more_body': False}
return await previous_receive()
receive = replay
if not write:
return await self.app(scope, receive, send)
lease = admission()
try:
lease.__enter__()
except BackupError as exc:
return await JSONResponse({'detail': str(exc), 'error': {'code': str(exc)}}, status_code=503)(scope, receive, send)
try:
await self.app(scope, receive, send)
finally:
lease.__exit__(None, None, None)