feat(integration): wire v2 workstreams together (engine policy/budget, sandbox, tenant checks, order route, docs)
Engine honours org policy and monthly budget, legacy runner skips engine tasks, sandbox session provisioned on demand, project fallback for threads, reviewer fallback, tenant checks on project ids, memory reflection respects grants, expiry worker, MCP pipeline_status, login redirect, sharing settings, e2e smoke. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5.5
parent
36564e3f2b
commit
fef5a9deab
@@ -2,6 +2,10 @@
|
||||
|
||||
Implemented by the org-platform workstream; used by the engine. FROZEN contract:
|
||||
see docs/plan/PLAN-v2.md §5. ``tier`` is a neutral label; users never see model names.
|
||||
|
||||
The contract was extended at integration: ``get_org_policy`` gives the engine the owner's
|
||||
per-organization policy (automation switch, employee cap, monthly budget). The port only
|
||||
reads it; the engine applies its own system ceiling (``settings.engine_max_employees``).
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -27,12 +31,48 @@ def tier_for(*, capabilities: list[str] | tuple[str, ...], output_price_per_1m:
|
||||
return "fast" if output_price_per_1m < 2.0 else "balanced"
|
||||
|
||||
|
||||
class OrgPolicyView(Protocol):
|
||||
"""Read-only view of one organization's owner policy.
|
||||
|
||||
Properties rather than attributes, so both a mutable dataclass (``ModelGrantService``'s
|
||||
``PolicyView``) and a frozen one (``DefaultOrgPolicy``) satisfy it.
|
||||
"""
|
||||
|
||||
@property
|
||||
def max_employees(self) -> int: ...
|
||||
|
||||
@property
|
||||
def automation_enabled(self) -> bool: ...
|
||||
|
||||
@property
|
||||
def mcp_enabled(self) -> bool: ...
|
||||
|
||||
@property
|
||||
def monthly_credit_budget(self) -> float | None: ...
|
||||
|
||||
|
||||
@dataclass(slots=True, frozen=True, kw_only=True)
|
||||
class DefaultOrgPolicy:
|
||||
"""The policy for an organization the owner has not configured.
|
||||
|
||||
``max_employees`` is only the port's default. The engine caps it with
|
||||
``settings.engine_max_employees`` itself, so this module does not import settings.
|
||||
"""
|
||||
|
||||
max_employees: int = 20
|
||||
automation_enabled: bool = True
|
||||
mcp_enabled: bool = True
|
||||
monthly_credit_budget: float | None = None
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class ModelGrantPort(Protocol):
|
||||
async def granted_models(self, *, organization_id: str) -> list[GrantedModel]: ...
|
||||
|
||||
async def is_granted(self, *, organization_id: str, ai_model_id: str) -> bool: ...
|
||||
|
||||
async def get_org_policy(self, organization_id: str) -> OrgPolicyView: ...
|
||||
|
||||
|
||||
class AllActiveModelsGrants:
|
||||
"""Today's behaviour: every active model is usable by every organization.
|
||||
@@ -48,3 +88,6 @@ class AllActiveModelsGrants:
|
||||
|
||||
async def is_granted(self, *, organization_id: str, ai_model_id: str) -> bool:
|
||||
return any(m.ai_model_id == ai_model_id for m in await self._list_active())
|
||||
|
||||
async def get_org_policy(self, organization_id: str) -> OrgPolicyView:
|
||||
return DefaultOrgPolicy()
|
||||
|
||||
Reference in New Issue
Block a user