mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-04-25 11:18:22 +00:00
Major refactoring of deerflow/runtime/: - runs/callbacks/ - new callback system (builder, events, title, tokens) - runs/internal/ - execution internals (executor, supervisor, stream_logic, registry) - runs/internal/execution/ - execution artifacts and events handling - runs/facade.py - high-level run facade - runs/observer.py - run observation protocol - runs/types.py - type definitions - runs/store/ - simplified store interfaces (create, delete, query, event) Refactor stream_bridge/: - Replace old providers with contract.py and exceptions.py - Remove async_provider.py, base.py, memory.py Add documentation: - README.md and README_zh.md for runtime module Remove deprecated: - manager.py moved to internal/ - worker.py, schemas.py - user_context.py Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
118 lines
3.1 KiB
Python
118 lines
3.1 KiB
Python
"""Request/task-scoped actor context for runtime-facing user isolation.
|
|
|
|
This module defines a runtime-owned context bridge that lower layers can
|
|
depend on without importing the auth plugin. The app/auth boundary maps
|
|
``request.user`` into :class:`ActorContext` and binds it before entering
|
|
runtime-facing code.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from contextvars import ContextVar, Token
|
|
from dataclasses import dataclass
|
|
from typing import Final
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class ActorContext:
|
|
user_id: str | None = None
|
|
# Future extension points:
|
|
# subject_id: str | None = None
|
|
# tenant_id: str | None = None
|
|
# scopes: frozenset[str] = frozenset()
|
|
# auth_source: str | None = None
|
|
|
|
|
|
_current_actor: Final[ContextVar[ActorContext | None]] = ContextVar(
|
|
"deerflow_actor_context",
|
|
default=None,
|
|
)
|
|
|
|
|
|
def bind_actor_context(actor: ActorContext) -> Token[ActorContext | None]:
|
|
"""Bind the current actor for this async task."""
|
|
|
|
return _current_actor.set(actor)
|
|
|
|
|
|
def reset_actor_context(token: Token[ActorContext | None]) -> None:
|
|
"""Restore the actor context captured by ``token``."""
|
|
|
|
_current_actor.reset(token)
|
|
|
|
|
|
def get_actor_context() -> ActorContext | None:
|
|
"""Return the current actor context, or ``None`` if unset."""
|
|
|
|
return _current_actor.get()
|
|
|
|
|
|
def require_actor_context() -> ActorContext:
|
|
"""Return the current actor context, or raise if unset."""
|
|
|
|
actor = _current_actor.get()
|
|
if actor is None:
|
|
raise RuntimeError("runtime accessed without actor context")
|
|
return actor
|
|
|
|
|
|
DEFAULT_USER_ID: Final[str] = "default"
|
|
|
|
|
|
def get_effective_user_id() -> str:
|
|
"""Return the effective user id, or ``DEFAULT_USER_ID`` if unset."""
|
|
|
|
actor = _current_actor.get()
|
|
if actor is None or actor.user_id is None:
|
|
return DEFAULT_USER_ID
|
|
return str(actor.user_id)
|
|
|
|
|
|
class _AutoSentinel:
|
|
"""Singleton marker meaning 'resolve user_id from actor context'."""
|
|
|
|
_instance: _AutoSentinel | None = None
|
|
|
|
def __new__(cls) -> _AutoSentinel:
|
|
if cls._instance is None:
|
|
cls._instance = super().__new__(cls)
|
|
return cls._instance
|
|
|
|
def __repr__(self) -> str:
|
|
return "<AUTO>"
|
|
|
|
|
|
AUTO: Final[_AutoSentinel] = _AutoSentinel()
|
|
|
|
|
|
def resolve_user_id(
|
|
value: str | None | _AutoSentinel,
|
|
*,
|
|
method_name: str = "repository method",
|
|
) -> str | None:
|
|
"""Resolve a repository ``user_id`` argument against the current actor."""
|
|
|
|
if isinstance(value, _AutoSentinel):
|
|
actor = _current_actor.get()
|
|
if actor is None or actor.user_id is None:
|
|
raise RuntimeError(
|
|
f"{method_name} called with user_id=AUTO but no actor context is set; "
|
|
"pass an explicit user_id, bind ActorContext at the app/runtime boundary, "
|
|
"or opt out with user_id=None for migration/CLI paths."
|
|
)
|
|
return str(actor.user_id)
|
|
return value
|
|
|
|
|
|
__all__ = [
|
|
"AUTO",
|
|
"ActorContext",
|
|
"DEFAULT_USER_ID",
|
|
"bind_actor_context",
|
|
"get_actor_context",
|
|
"get_effective_user_id",
|
|
"require_actor_context",
|
|
"reset_actor_context",
|
|
"resolve_user_id",
|
|
]
|