Ctrl K
ComunidadGuías…

src/webui/services/assistant_authorization.py

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
"""Server-held, owner-session authorization for bounded Agent tasks."""
from __future__ import annotations

from copy import deepcopy

SCOPE_KEYS = frozenset({'game_key', 'world_id', 'book_id', 'card_id'})


def make_authorization(mode, scope, domains, max_steps, now):
    if mode not in {'suggest', 'routine', 'task'}:
        raise ValueError('Unknown authorization mode')
    if (not isinstance(scope, dict) or set(scope) - SCOPE_KEYS
            or any(not isinstance(value, str) or not 1 <= len(value) <= 500 for value in scope.values())):
        raise ValueError('Invalid authorization scope')
    if (not isinstance(domains, list) or len(domains) > 16 or len(set(domains)) != len(domains)
            or any(not isinstance(value, str) or not value or len(value) > 40 for value in domains)):
        raise ValueError('Invalid authorization domains')
    if type(max_steps) is not int or not 1 <= max_steps <= 64:
        raise ValueError('Action budget must be between 1 and 64')
    if mode == 'suggest':
        return None
    return {'mode': mode, 'scope': deepcopy(scope), 'domains': list(domains), 'max_steps': max_steps,
            'remaining_steps': max_steps, 'expires_at': now + (3600 if mode == 'task' else 14400)}


def current_authorization(data, now):
    value = data.get('authorization')
    if (not isinstance(value, dict) or value.get('expires_at', 0) <= now
            or value.get('remaining_steps', 0) <= 0):
        return None
    return deepcopy(value)


def permits(grant, action, arguments, assessment=None):
    effect = assessment.effect if assessment is not None else action.effective_effect
    if (not grant or effect in {'destructive', 'external'}
            or (assessment is not None and assessment.requires_approval)):
        return False
    if grant['domains'] and action.domain not in grant['domains']:
        return False
    scope = grant['scope']
    targets = assessment.targets if assessment is not None and assessment.targets else (arguments,)
    if scope:
        if any(any(key not in target or scope[key] != target[key] for key in scope) for target in targets):
            return False
    if grant['mode'] == 'routine':
        return action.automatic and effect == 'write'
    return grant['mode'] == 'task' and effect in {'write', 'disclosure'}